bknr-cvs
Threads by month
- ----- 2025 -----
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
November 2007
- 1 participants
- 33 discussions

[bknr-cvs] r2284 - in branches/trunk-reorg/projects/scrabble: src website website/images/de website/images/en
by bknr@bknr.net 17 Nov '07
by bknr@bknr.net 17 Nov '07
17 Nov '07
Author: hhubner
Date: 2007-11-17 05:28:57 -0500 (Sat, 17 Nov 2007)
New Revision: 2284
Added:
branches/trunk-reorg/projects/scrabble/website/images/de/cursor.png
branches/trunk-reorg/projects/scrabble/website/images/de/mask.png
branches/trunk-reorg/projects/scrabble/website/images/en/cursor.png
branches/trunk-reorg/projects/scrabble/website/images/en/mask.png
Modified:
branches/trunk-reorg/projects/scrabble/src/make-letters.lisp
branches/trunk-reorg/projects/scrabble/website/scrabble.js
Log:
Cursor image, mask image for placed tiles, don't consider placed tiles
for move legality determination.
Modified: branches/trunk-reorg/projects/scrabble/src/make-letters.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/make-letters.lisp 2007-11-15 14:10:11 UTC (rev 2283)
+++ branches/trunk-reorg/projects/scrabble/src/make-letters.lisp 2007-11-17 10:28:57 UTC (rev 2284)
@@ -1,43 +1,44 @@
-
(in-package :scrabble.graphics)
-(defparameter *special-tile-texts* (make-hash-table))
+(defparameter *special-field-texts* (make-hash-table))
-(setf (gethash :de *special-tile-texts*)
+(setf (gethash :de *special-field-texts*)
'(:double-letter "DOPPELTER
BUCHSTABEN
WERT"
- :double-word "DOPPELTER
+ :double-word "DOPPELTER
WORT
WERT"
- :triple-letter "DREIFACHER
+ :triple-letter "DREIFACHER
BUCHSTABEN
WERT"
- :triple-word "DREIFACHER
+ :triple-word "DREIFACHER
WORT
WERT"))
-(setf (gethash :en *special-tile-texts*)
+(setf (gethash :en *special-field-texts*)
'(:double-letter "DOUBLE
LETTER
SCORE"
- :double-word "DOUBLE
+ :double-word "DOUBLE
WORD
SCORE"
- :triple-letter "TRIPLE
+ :triple-letter "TRIPLE
LETTER
SCORE"
- :triple-word "TRIPLE
+ :triple-word "TRIPLE
WORD
SCORE"))
-(defparameter *special-tile-colors*
+(defparameter *special-field-colors*
'(:double-letter (0.53 0.8 0.94)
:double-word (0.97 0.67 0.6)
:triple-letter (0.0 0.62 0.87)
:triple-word (0.93 0.11 0.18)
:standard (0.0 0.59 0.57)))
+(defparameter *tile-color* '(1.0 0.98 0.8))
+
(defparameter *bold-font* #.(merge-pathnames #p"../fonts/DIN/DINMd___.ttf" *default-pathname-defaults*))
(defparameter *regular-font* #.(merge-pathnames #p"../fonts/DIN/DINRg___.ttf" *default-pathname-defaults*))
@@ -50,7 +51,7 @@
(char-name char)
char-string)
:type "png")))
- (set-rgb-fill 1.0 0.98 0.8)
+ (apply #'set-rgb-fill *tile-color*)
(rounded-rectangle 0 0 34 34 4 4)
(fill-path)
(when char
@@ -62,6 +63,13 @@
(save-png pathname)
pathname)))
+(defun make-mask-tile ()
+ (with-canvas (:width 34 :height 34)
+ (apply #'set-rgba-fill (append *tile-color* (list 0.5)))
+ (rounded-rectangle 0 0 34 34 4 4)
+ (fill-path)
+ (save-png #P"mask.png")))
+
(defun make-letter-tile-set (language)
(with-open-file (letter-map-file "charmap.xml"
:direction :output
@@ -76,7 +84,15 @@
(cxml:attribute "filename" (namestring (make-letter-tile letter score)))
(cxml:text (princ-to-string letter)))))))))
-(defun make-special-tile (name color &key text star)
+(defun make-cursor ()
+ (with-canvas (:width 46 :height 46)
+ (apply #'set-rgb-stroke *tile-color*)
+ (set-line-width 5)
+ (rounded-rectangle 4 4 38 38 5 5)
+ (stroke)
+ (save-png #P"cursor.png")))
+
+(defun make-special-field (name color &key text star)
(with-canvas (:width 40 :height 40)
(let ((regular-font (get-font *regular-font*)))
(apply #'set-rgb-fill color)
@@ -84,26 +100,25 @@
(fill-path)
(set-rgb-fill 0 0 0)
(cond
- (text
- (set-font regular-font 6)
+ (text
+ (set-font regular-font 6)
(let* ((lines (cl-ppcre:split "\\n" text))
(position (+ 20 (* 6 (/ 2 (length lines))))))
(dolist (line lines)
(draw-centered-string 20 position line)
(decf position 6))))
- (star
- ))
+ (star
+ ))
(save-png (make-pathname :name (string-downcase (symbol-name name)) :type "png")))))
-(defun make-special-tile-set (language)
+(defun make-special-field-set (language)
(dolist (tile-name '(:double-letter :double-word :triple-letter :triple-word))
- (make-special-tile tile-name
- (getf *special-tile-colors* tile-name)
- :text (getf (gethash language *special-tile-texts*) tile-name)))
- (make-special-tile :standard (getf *special-tile-colors* :standard) :star nil)
- (make-special-tile :standard (getf *special-tile-colors* :double-word) :star t))
+ (make-special-field tile-name
+ (getf *special-field-colors* tile-name)
+ :text (getf (gethash language *special-field-texts*) tile-name)))
+ (make-special-field :standard (getf *special-field-colors* :standard) :star nil)
+ (make-special-field :standard (getf *special-field-colors* :double-word) :star t))
-
(defun make-tile-set (directory language)
(let ((*default-pathname-defaults*
(merge-pathnames (merge-pathnames (make-pathname
@@ -111,5 +126,5 @@
directory))))
(ensure-directories-exist *default-pathname-defaults*)
(make-letter-tile-set language)
- (make-special-tile-set language)))
-
+ (make-special-field-set language)
+ (make-cursor)))
Added: branches/trunk-reorg/projects/scrabble/website/images/de/cursor.png
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/projects/scrabble/website/images/de/cursor.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/projects/scrabble/website/images/de/mask.png
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/projects/scrabble/website/images/de/mask.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/projects/scrabble/website/images/en/cursor.png
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/projects/scrabble/website/images/en/cursor.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/projects/scrabble/website/images/en/mask.png
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/projects/scrabble/website/images/en/mask.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: branches/trunk-reorg/projects/scrabble/website/scrabble.js
===================================================================
--- branches/trunk-reorg/projects/scrabble/website/scrabble.js 2007-11-15 14:10:11 UTC (rev 2283)
+++ branches/trunk-reorg/projects/scrabble/website/scrabble.js 2007-11-17 10:28:57 UTC (rev 2284)
@@ -74,8 +74,8 @@
}
}
}
-
-
+
+
//
function getFieldScore(x, y) {
@@ -138,27 +138,35 @@
// appendChildNodes(container, clearButton);
}
-function setLetter(x, y, letter) {
+function setLetter(x, y, letter, justPlaced) {
var image = IMG({ src: 'images/' + letter + '.png'});
image.style.position = 'absolute';
image.style.top = '3px';
image.style.left = '3px';
replaceChildNodes(board[x][y], image);
+ if (justPlaced) {
+ var mask = IMG({ src: 'images/mask.png'});
+ mask.style.position = 'absolute';
+ mask.style.top = '3px';
+ mask.style.left = '3px';
+ appendChildNodes(board[x][y], mask);
+ }
board[x][y].letterNode = image;
board[x][y].letter = letter;
+ board[x][y].justPlaced = justPlaced;
YAHOO.util.Event.purgeElement(board[x][y], false, 'click');
}
function letterAt(x, y) {
- return board[x][y].letter;
+ return board[x][y].letter && !board[x][y].justPlaced;
}
function Cursor()
{
- var image = new IMG({ src: 'images/NIL.png' });
+ var image = new IMG({ src: 'images/cursor.png' });
image.style.position = 'absolute';
- image.style.top = '3px';
- image.style.left = '3px';
+ image.style.top = '-3px';
+ image.style.left = '-3px';
this.image = image;
this.x = -1;
@@ -233,12 +241,13 @@
function makeMove(x, y, letter) {
move[move.length] = [x, y, letter];
- $('move').onclick = submitMove;
- $('move').innerHTML = move.toString();
try {
checkMoveLegality(move);
+ $('move').onclick = submitMove;
+ $('move').innerHTML = move.toString();
}
catch (e) {
+ $('move').onclick = undefined;
$('move').innerHTML = e.toString();
}
}
@@ -291,7 +300,7 @@
var x = cursor.x;
var y = cursor.y;
cursor.advance();
- setLetter(x, y, letter);
+ setLetter(x, y, letter, true);
makeMove(x, y, letter);
}
@@ -304,7 +313,7 @@
function functionKeyPressed(type, args, obj) {
var x = cursor.x;
var y = cursor.y;
-
+
switch (args[0]) {
case rightKey:
while (x < 14)
1
0

15 Nov '07
Author: hhubner
Date: 2007-11-15 09:10:11 -0500 (Thu, 15 Nov 2007)
New Revision: 2283
Modified:
branches/trunk-reorg/bknr/datastore/src/data/txn.lisp
Log:
Remove redundant call to ensure-store-random-state
Modified: branches/trunk-reorg/bknr/datastore/src/data/txn.lisp
===================================================================
--- branches/trunk-reorg/bknr/datastore/src/data/txn.lisp 2007-11-15 07:42:51 UTC (rev 2282)
+++ branches/trunk-reorg/bknr/datastore/src/data/txn.lisp 2007-11-15 14:10:11 UTC (rev 2283)
@@ -79,7 +79,6 @@
(setf *store* store)
(let ((store-existed-p (probe-file (store-current-directory store))))
(ensure-store-current-directory store)
- (ensure-store-random-state store)
(dolist (subsystem (store-subsystems store))
(when *store-debug*
(format *trace-output* "Initializing subsystem ~A of ~A~%" subsystem store))
1
0

[bknr-cvs] r2282 - in branches/trunk-reorg/thirdparty: . hunchentoot-0.14.7 hunchentoot-0.14.7/doc hunchentoot-0.14.7/test slime slime/CVS slime/contrib slime/contrib/CVS slime/doc/CVS
by bknr@bknr.net 15 Nov '07
by bknr@bknr.net 15 Nov '07
15 Nov '07
Author: hhubner
Date: 2007-11-15 02:42:51 -0500 (Thu, 15 Nov 2007)
New Revision: 2282
Added:
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/CHANGELOG
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/CHANGELOG_TBNL
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/README
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/conditions.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/cookie.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/LICENSE.txt
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/hunchentoot.gif
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/index.html
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/easy-handlers.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/headers.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/hunchentoot-test.asd
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/hunchentoot.asd
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/log.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/mime-types.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/misc.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/packages.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-acl.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-cmu.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-lw.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-mcl.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-sbcl.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/reply.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/request.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/server.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/session.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/specials.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/UTF-8-demo.html
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/favicon.ico
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/fz.jpg
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/packages.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/test.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-acl.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-cmu.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-lw.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-mcl.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-sbcl.lisp
branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/util.lisp
Removed:
branches/trunk-reorg/thirdparty/hunchentoot-0.14.6/
Modified:
branches/trunk-reorg/thirdparty/slime/CVS/Entries
branches/trunk-reorg/thirdparty/slime/ChangeLog
branches/trunk-reorg/thirdparty/slime/contrib/CVS/Entries
branches/trunk-reorg/thirdparty/slime/contrib/ChangeLog
branches/trunk-reorg/thirdparty/slime/contrib/swank-arglists.lisp
branches/trunk-reorg/thirdparty/slime/doc/CVS/Entries
branches/trunk-reorg/thirdparty/slime/slime.el
branches/trunk-reorg/thirdparty/slime/swank-abcl.lisp
branches/trunk-reorg/thirdparty/slime/swank-loader.lisp
branches/trunk-reorg/thirdparty/slime/swank-openmcl.lisp
branches/trunk-reorg/thirdparty/slime/swank.lisp
Log:
update hunchentoot
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/CHANGELOG
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/CHANGELOG 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/CHANGELOG 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,277 @@
+Version 0.14.7
+2007-11-15
+Replace ENOUGH-NAMESTRING with ENOUGH-URL (patch by Kilian Sprotte and Hans H�bner)
+
+Version 0.14.6
+2007-11-08
+Fix compilation order (thanks to Tiarnan O'Corrain and Chris Dean)
+
+Version 0.14.5
+2007-10-21
+Robustified MAKE-SOCKET-STREAM against potential leak (thanks to Alain Picard)
+Replaced #-FOO #-FOO constructs for OpenMCL (patch by Michael Weber)
+Updated tutorial links
+
+Version 0.14.4
+2007-10-20
+Made log stream shared on OpenMCL (thanks to Gary Byers)
+
+Version 0.14.3
+2007-10-07
+Enabled GET-GID-FROM-NAME for newer versions of SBCL (patch by Cyrus Harmon)
+
+Version 0.14.2
+2007-09-26
+Better handling of PORT parameter in REDIRECT (thanks to Vladimir Sedach)
+
+Version 0.14.1
+2007-09-24
+Fixed bug where you couldn't set "Server" header (caught by Ralf Mattes)
+Documentation clarification for HEADER-OUR function
+
+Version 0.14.0
+2007-09-18
+Added support for "HttpOnly" cookie attribute
+
+Version 0.13.0
+2007-09-14
+Added *METHODS-FOR-POST-PARAMETERS* (suggested by Jonathon McKitrick)
+
+Version 0.12.1
+2007-09-13
+Better support for WITH-TIMEOUT on SBCL/Win32 (thanks to Anton Vodonosov)
+
+Version 0.12.0
+2007-09-07
+Now uses bound for flexi stream returned by RAW-POST-DATA
+Needs FLEXI-STREAMS 0.12.0 or higher
+
+Version 0.11.2
+2007-09-05
+Fixed typo in docs
+Added declaration in server.lisp to appease SBCL
+
+Version 0.11.1
+2007-05-25
+Fixes for OpenMCL (thanks to Lennart Staflin and Tiarnan O'Corrain)
+
+Version 0.11.0
+2007-05-25
+Added server names and coupled them with easy handlers (suggested by Mac Chan)
+Exported SESSION-COOKIE-VALUE instead of SESSION-STRING (suggested by Slava Akhmechet)
+Documentation fixes (thanks to Victor Kryukov and Igor Plekhov)
+
+Version 0.10.0
+2007-05-12
+Made MAYBE-INVOKE-DEBUGGER a generic function and exported it (suggested by Vladimir Sedach)
+
+Version 0.9.3
+2007-05-08
+Fixed CREATE-FOLDER-DISPATCHER-AND-HANDLER in the presence of URL-encoded URLs (bug caught by Nicolas Lamirault)
+
+Version 0.9.2
+2007-05-01
+Made DEF-HTTP-RETURN-CODE more flexible (suggested by Jong-won Choi)
+
+Version 0.9.1
+2007-04-29
+Added PORT parameter to REDIRECT (suggested by Cyrus Harmon)
+Exported REMOVE-SESSION (suggested by Vamsee Kanakala)
+
+Version 0.9.0
+2007-04-19
+Added socket timeouts for AllegroCL
+Catch IO timeout conditions for AllegroCL, SBCL and CMUCL (suggested by Red Daly and others)
+Added per-server dispatch tables (suggested by Robert Synnott and Andrei Stebakov)
+
+Version 0.8.6
+2007-04-18
+USE the CL package explicitly when defining HUNCHENTOOT-MP (bug report by Joel Boehland)
+
+Version 0.8.5
+2007-04-10
+Correct behaviour for "100 Continue" responses
+
+Version 0.8.4
+2007-04-09
+Cleanup
+
+Version 0.8.3
+2007-04-07
+Don't use chunked encoding for empty (NIL) bodies
+
+Version 0.8.2
+2007-04-05
+Really exported REASON-PHRASE this time (and also *CURRENT-PROCESS*)
+
+Version 0.8.1
+2007-04-04
+Added HUNCHENTOOT-MP package (suggested by Cyrus Harmon)
+Only invoke MARK-AND-SWEEP for 32-bit versions of LW (thanks to Chris Dean)
+Exported REASON-PHRASE
+
+Version 0.8.0
+2007-03-31
+Added *APPROVED-RETURN-CODES*, *HEADER-STREAM*, and +HTTP-FAILED-DEPENDENCY+
+Exported MIME-TYPE and SSL-P
+Some minor changes
+
+Version 0.7.3
+2007-03-28
+Added +HTTP-MULTI-STATUS+
+
+Version 0.7.2
+2007-03-09
+Fix test suite to properly handle non-base characters in LW (bug caught by Jong-won Choi)
+
+Version 0.7.1
+2007-03-09
+Fixed last change (thanks to Marko Kocic)
+
+Version 0.7.0
+2007-03-09
+Development port (no threads) to SBCL/Win32 (patch by Marko Kocic)
+Support for compilation without SSL
+
+Version 0.6.2
+2007-02-22
+Don't use NSTRING-UPCASE for outgoing headers (bug caught by Saurabh Nanda)
+Changed ProxyPass example in docs from /lisp to /hunchentoot
+
+Version 0.6.1
+2007-01-24
+Reset to "faithful" external format on each iteration (bug caught by Viljo Marrandi and Ury Marshak)
+
+Version 0.6.0
+2007-01-23
+Accept chunked transfer encoding for mod_lisp request bodies (thanks to Hugh Winkler's mod_lisp additions)
+Robustify against erroneous form-data submissions (caught by Ury Marshak)
+
+Version 0.5.1
+2007-01-18
+Even more flexible behaviour of RAW-POST-DATA
+
+Version 0.5.0
+2007-01-17
+More flexible behaviour of RAW-POST-DATA
+Robustified PARSE-CONTENT-TYPE
+
+Version 0.4.14
+2007-01-17
+More meaningful results for RAW-POST-DATA
+
+Version 0.4.13
+2007-01-14
+Added favicon.ico to example website (thanks to Yoni Rabkin Katzenell, Toby, and Uwe von Loh)
+
+Version 0.4.12
+2006-12-27
+Added Hunchentoot logo by Uwe von Loh
+
+Version 0.4.11
+2006-12-01
+Exported symbols related to session GC (suggested by Nico de Jager)
+
+Version 0.4.10
+2006-11-19
+Added *HANDLE-HTTP-ERRORS-P* (thanks to Marijn Haverbeke)
+Remove duplicate headers when reading from mod_lisp
+
+Version 0.4.9
+2006-11-12
+Fixed HEADER-OUT (thanks to Robert J. Macomber)
+
+Version 0.4.8
+2006-11-06
+Fixed bug in START-OUTPUT which confused mod_lisp
+
+Version 0.4.7
+2006-11-06
+Changed behaviour of REAL-REMOTE-ADDR (as suggested by Robert J. Macomber)
+Fixed COOKIE-OUT (thanks to Robert J. Macomber)
+
+Version 0.4.6
+2006-11-05
+Don't bind *DISPATCH-TABLE* too early (thanks to Marijn Haverbeke)
+
+Version 0.4.5
+2006-10-25
+Fixed bug in AUTHORIZATION function (reported by Michael J. Forster)
+
+Version 0.4.4
+2006-10-12
+Correct SSL check in REDIRECT function
+LOG-MESSAGE now checks for (BOUNDP '*SERVER*)
+
+Version 0.4.3
+2006-10-11
+OpenMCL fixes (by Ralf Stoye)
+
+Version 0.4.2
+2006-10-10
+No timeouts for mod_lisp servers (as in Hunchentoot 0.3.x)
+
+Version 0.4.1
+2006-10-10
+Fixed a typo in easy-handlers.lisp (caught by Travis Cross)
+
+Version 0.4.0
+2006-10-10
+Ported to CMUCL, SBCL, OpenMCL, and AllegroCL
+Merged with TBNL
+Tons of small changes, too many to list them individually
+
+Version 0.3.2
+2006-09-14
+Uses TBNL's WITH-DEBUGGER now
+
+Version 0.3.1
+2006-09-14
+Added *CATCH-ERRORS-P* (from TBNL)
+
+Version 0.3.0
+2006-09-05
+Accept HTTP requests with chunked transfer encoding
+Use Chunga for chunking
+
+Version 0.2.2
+2006-08-31
+Skip START-OUTPUT advice completely if working for TBNL
+
+Version 0.2.1
+2006-08-28
+Added write timeouts for LW 5.0
+Updated LW links in documentation
+
+Version 0.2.0
+2006-08-28
+Serves as infrastructure for TBNL now (to replace KMRCL)
+For HTTP/1.1 only send 'Keep-Alive' headers if explicitly requested
+
+Version 0.1.5
+2006-08-23
+Connection headers are separated by commas, not semicolons
+
+Version 0.1.4
+2006-08-22
+Refactored streams.lisp to appease LW compiler (thanks to Martin Simmons)
+Changed handling of version string
+Changed package handling in system definition (thanks to Christophe Rhodes)
+
+Version 0.1.3
+2006-02-08
+Removed KMRCL workaround
+
+Version 0.1.2
+2006-01-03
+Mention TBNL version number in server name header
+
+Version 0.1.1
+2005-12-31
+Fixed package stuff and HYPERDOC support
+
+Version 0.1.0
+2005-12-31
+Initial public release
+
+[For earlier changes see the file "CHANGELOG_TBNL" that is included with the release.]
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/CHANGELOG
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/CHANGELOG_TBNL
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/CHANGELOG_TBNL 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/CHANGELOG_TBNL 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,340 @@
+Version 0.11.3
+2006-09-30
+Added *FILE-UPLOAD-HOOK* (suggested by Erik Enge)
+Fixed DEFINE-EASY-HANDLER for cases where URI is NIL
+
+Version 0.11.2
+2006-09-20
+DEFINE-EASY-HANDLER: fixed and clarified redefinition
+DEFINE-EASY-HANDLER: allow for functions designators as "URIs"
+DEFINE-EASY-HANDLER: take file uploads into account
+Made logging a little bit more robust
+Added mime type for XSL-FO (.fo)
+
+Version 0.11.1
+2006-09-14
+Cleaner implementation of *CATCH-ERRORS-P*
+
+Version 0.11.0
+2006-09-14
+Added *CATCH-ERRORS-P*
+
+Version 0.10.3
+2006-09-05
+Appease SBCL (thanks to Juho Snellman)
+
+Version 0.10.2
+2006-09-05
+Better reporting of IP addresses and ports if not behind mod_lisp
+Improved logging
+Fixed REAL-REMOTE-ADDR
+Cookies always use UTF-8 encoding (which is opaque to the client anyway)
+Read request bodies without 'Content-Length' header (for Hunchentoot)
+Removed accented character from test.lisp to appease SBCL (reported by Xristos Kalkanis)
+
+Version 0.10.1
+2006-08-31
+Only LispWorks: Set read timeout to NIL if connected to mod_lisp
+
+Version 0.10.0
+2006-08-28
+Based LispWorks version of TBNL on Hunchentoot infrastructure
+Added "easy" handlers
+Exported GET-BACKTRACE (suggested by Erik Enge)
+
+Version 0.9.11
+2006-08-16
+Added note about SBCL problems
+
+Version 0.9.10
+2006-05-24
+Prepare for LW 5.0 release
+
+Version 0.9.9
+2006-05-12
+Workaround for something like "application/x-www-form-urlencoded;charset=UTF-8" (caught by John Bates)
+
+Version 0.9.8
+2006-04-25
+For mod_lisp, Lisp-Content-Length header must be sent after Content-Length header
+
+Version 0.9.7
+2006-02-06
+More robust computation of content length
+
+Version 0.9.6
+2006-01-22
+Added the missing piece (argh!)
+
+Version 0.9.5
+2006-01-22
+Made creation of REQUEST object safer (thanks to Robert J. Macomber)
+Replaced some erroneous DECLAIMs with DECLAREs (thanks to SBCL's style warnings)
+Slight documentation enhancements
+
+Version 0.9.4
+2006-01-03
+Handle "Expect: 100-continue" for non-Apache front-ends
+Re-introduced IGNORE-ERRORS in GET-REQUEST-DATA
+
+Version 0.9.3
+2006-01-01
+Fixed bug in READ-HTTP-REQUEST
+
+Version 0.9.2
+2005-12-31
+Protocol of reply is HTTP/1.1 now
+Made HTTP/0.9 default protocol of request if none was provided
+Some preparations for Hunchentoot
+Various minor changes
+Small fixes in docs
+
+Version 0.9.1
+2005-12-25
+Added missing file mime-types.lisp (thanks to Hilverd Reker)
+
+Version 0.9.0
+2005-12-24
+Experimental support for writing directly to the front-end (see SEND-HEADERS)
+Added HANDLE-STATIC-FILE
+Changed CREATE-STATIC-FILE-DISPATCHER-AND-HANDLER to use new facilities
+Added CREATE-FOLDER-DISPATCHER-AND-HANDLER
+Added link to Travis Cross' message w.r.t. SBCL
+
+Version 0.8.9
+2005-12-16
+Also use :TBNL-BIVALENT-STREAMS if :SB-UNICODE is present
+
+Version 0.8.8
+2005-12-08
+Made RAW-POST-DATA more useful
+Updated docs w.r.t. Araneida (thanks to Alan Shields)
+
+Version 0.8.7
+2005-11-29
+Made "Content-Length" header SETFable
+
+Version 0.8.6
+2005-11-18
+Restored original stream-based code for multipart/form-data parsing (got lost somehow)
+Wrapped REMOTE-ADDR with IGNORE-ERRORS (just in case)
+
+Version 0.8.5
+2005-11-14
+Added generic function DISPATCH-REQUEST (thanks to Jeff Caldwell)
+
+Version 0.8.4
+2005-10-21
+Provide REMOTE-ADDR if connected directly (for LispWorks and AllegroCL)
+Show remote user and address (if available) in non-Apache logs
+Mention Debian package in docs
+
+Version 0.8.3
+2005-10-10
+Alert LW users that a patch for OCTETS-TO-STRINGS is available (thanks to LispWorks support)
+
+Version 0.8.2
+2005-10-06
+Make STRING-TO-OCTETS and OCTETS-TO-STRING safer for LW
+
+Version 0.8.1
+2005-09-29
+Bugfix in CMUCL version of STRING-TO-OCTETS
+
+Version 0.8.0
+2005-09-24
+Added the ability to cope with different external formats (incorporating suggestions from Will Glozer and Ivan Shvedunov)
+Raw post data is now always saved (so *SAVE-RAW-POST-DATA-P* is gone)
+
+Version 0.7.0
+2005-09-17
+Added the ability to store arbitrary data within REQUEST objects (suggested by Zach Beane)
+Fixed handling of *HTTP-ERROR-HANDLER*
+Note: *TBNL-VERSION* was wrong in 0.6.0 and 0.6.1
+
+Version 0.6.1
+2005-09-10
+Robustified socket handling code
+
+Version 0.6.0
+2005-09-08
+Added TBNL-CONTRIB package
+Added contrib directory with first entry (from Alceste Scalas)
+Updated link to Bill Clementson's blog
+Don't redefine what's already there (for LispWorks)
+
+Version 0.5.5
+2005-04-18
+Make RFC 2388 code an external dependency (thanks to Janis Dzerins)
+
+Version 0.5.4
+2005-04-03
+Fixed dumb typo (caught by Bob Hutchison)
+
+Version 0.5.3
+2005-04-03
+Re-introduced automatic front-end selection (originally by Bob Hutchison)
+
+Version 0.5.2
+2005-03-26
+Fixed bug in modlisp.html where *CLOSE-TBNL-STREAM* could be NIL although it should be T
+Set correct content type for 304 replies
+
+Version 0.5.1
+2005-03-17
+Changed default cookie path in START-SESSION (suggested by Stefan Scholl)
+Small bugfixes
+More headers from the Araneida front-end
+Added *SHOW-ACCESS-LOG-MESSAGES*
+Changed "back-end" to "front-end" :)
+
+Version 0.5.0
+2005-03-17
+Initial support for "stand-alone" version (no front-end) (supplied by Bob Hutchison)
+New logging API
+Fixes in START-TBNL/STOP-TBNL
+Documentation enhancements
+
+Version 0.4.1
+2005-03-15
+Fixed some typos, removed unused code
+
+Version 0.4.0
+2005-03-14
+Initial Araneida support (supplied by Bob Hutchison)
+
+Version 0.3.13
+2005-03-12
+Small bugfix in RFC-1123-DATE (thanks to Bob Hutchison and Stefan Scholl)
+
+Version 0.3.12
+2005-03-01
+Added *HTTP-ERROR-HANDLER* (suggested and coded by Stefan Scholl)
+Exported and documented *SESSION-MAX-TIME*
+
+Version 0.3.11
+2005-02-21
+Added ability to access raw post data (suggested and coded by Zach Beane)
+
+Version 0.3.10
+2005-01-24
+Make bivalent streams work with LispWorks 4.4
+UTF-8 demo for LispWorks (thanks to Bob Hutchison)
+
+Version 0.3.9
+2004-12-31
+Re-compute content length after applying MAYBE-REWRITE-URLS-FOR-SESSION (caught by Stefan Scholl)
+
+Version 0.3.8
+2004-12-27
+Don't send body for HEAD requests (needs current mod_lisp version)
+
+Version 0.3.7
+2004-12-22
+Change #\Del to #\Rubout in QUOTE-STRING (AllegroCL complains, #\Del isn't even semi-standard)
+
+Version 0.3.6
+2004-12-02
+Make REQUIRE-AUTHORIZATION compliant to RFC 2616 (thanks to Stefan Scholl)
+
+Version 0.3.5
+2004-12-01
+Several small doc fixes (thanks to Stefan Scholl)
+Catch requests like "GET http://server/foo.html HTTP/1.0" (suggested by Stefan Scholl)
+
+Version 0.3.4
+2004-11-29
+Added backtrace code for OpenMCL (provided by Tiarn�n � Corr�in)
+
+Version 0.3.3
+2004-11-22
+Cleaner handling of macro variables
+
+Version 0.3.2
+2004-11-11
+Updated docs for mod_lisp2
+
+Version 0.3.1
+2004-11-09
+Slight changes to support Chris Hanson's mod_lisp2
+Changed GET-BACKTRACE for newer SBCL versions (thanks to Nikodemus Siivola)
+
+Version 0.3.0
+2004-11-09
+Initial support for multipart/form-data (thanks to Michael Weber and Janis Dzerins)
+Fixed bug in CREATE-STATIC-FILE-DISPATCHER-AND-HANDLER (caught by Bill Clementson)
+
+Version 0.2.12
+2004-10-15
+Exported and documented DO-SESSIONS
+
+Version 0.2.11
+2004-09-02
+FORM-URL-ENCODED-LIST-TO-ALIST now decodes names and values
+
+Version 0.2.10
+2004-08-28
+Allow non-strings to be cookie values (bug caught by Zach Beane)
+
+Version 0.2.9
+2004-08-11
+Consistent usage of RFC-1123-DATE (provided by Stefan Scholl)
+Added all missing http headers from RFC 2616 (provided by Stefan Scholl)
+Added support for mod_lisp version strings (see <http://common-lisp.net/pipermail/mod-lisp-devel/2004-August/000019.html>)
+Don't always add session IDs when redirecting
+
+Version 0.2.8
+2004-07-24
+Fixed typo in html.lisp and improved docs (both caught by Stefan Scholl)
+
+Version 0.2.7
+2004-07-24
+Add missing exports and docs
+
+Version 0.2.6
+2004-07-24
+Make CREATE-STATIC-FILE-DISPATCHER-AND-HANDLER thread-safe (caught by Jeff Caldwell)
+Added support for 'If-Modified-Since' request headers (provided by Stefan Scholl)
+
+Version 0.2.5
+2004-07-21
+Added CREATE-STATIC-FILE-DISPATCHER-AND-HANDLER (provided by Stefan Scholl)
+Improved test suite
+
+Version 0.2.4
+2004-07-19
+New variable *CONTENT-TYPES-FOR-URL-REWRITE* (suggested by Stefan Scholl)
+Updated index.html regarding new version of mod_lisp
+
+Version 0.2.3
+2004-06-12
+Bugfix for FORM-URL-ENCODED-LIST-TO-ALIST (bug caught by Jong-won Choi)
+
+Version 0.2.2
+2004-06-10
+Bugfix for SESSION-GC and RESET-SESSIONS (bug introduced in 0.2.0)
+
+Version 0.2.1
+2004-06-10
+Only create backtrace if needed (speeds up AllegroCL considerably)
+
+Version 0.2.0
+2004-06-07
+Added SESSION-STRING and *SESSION-REMOVAL-HOOK*
+Added GET-BACKTRACE for AllegroCL
+
+Version 0.1.2
+2004-05-12
+Removed some more typos in docs (thanks to Karl A. Krueger)
+Changed BASE64 to CL-BASE64 in .asd file (thanks to Frank Sonnemans and Nicolas Lamirault)
+
+Version 0.1.1
+2004-05-08
+Removed some old files from Jeff's port
+Fixed a couple of typos in docs
+
+Version 0.1.0
+2004-05-07
+First public release
+Original code by Edi Weitz
+Initial doc strings, port to KMRCL, logging code and various other improvements by Jeff Caldwell
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/README
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/README 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/README 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,2 @@
+Complete documentation for Hunchentoot including details about how to
+install it can be found in the 'doc' directory.
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/README
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/conditions.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/conditions.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/conditions.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,60 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/conditions.lisp,v 1.1 2007/11/08 20:07:58 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(defvar *catch-errors-p* t
+ "Whether Hunchentoot should catch and log errors \(or rather
+invoke the debugger).")
+
+(defgeneric maybe-invoke-debugger (condition)
+ (:documentation "This generic function is called whenever a
+condition CONDITION is signaled in Hunchentoot. You might want to
+specialize it on specific condition classes for debugging purposes.")
+ (:method (condition)
+ "The default method invokes the debugger with CONDITION if
+*CATCH-ERRORS-P* is NIL."
+ (unless *catch-errors-p*
+ (invoke-debugger condition))))
+
+(defmacro with-debugger (&body body)
+ "Executes BODY and invokes the debugger if an error is signaled and
+*CATCH-ERRORS-P* is NIL."
+ `(handler-bind ((error #'maybe-invoke-debugger))
+ ,@body))
+
+(defmacro ignore-errors (&body body)
+ "Like CL:IGNORE-ERRORS, but observes *CATCH-ERRORS-P*."
+ `(cl:ignore-errors (with-debugger ,@body)))
+
+(defmacro handler-case (expression &rest clauses)
+ "Like CL:HANDLER-CASE, but observes *CATCH-ERRORS-P*."
+ `(cl:handler-case (with-debugger ,expression)
+ ,@clauses))
+
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/conditions.lisp
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/cookie.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/cookie.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/cookie.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,121 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/cookie.lisp,v 1.7 2007/09/18 14:23:23 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(defclass cookie ()
+ ((name :initarg :name
+ :reader cookie-name
+ :type string
+ :documentation "The name of the cookie - a string.")
+ (value :initarg :value
+ :accessor cookie-value
+ :initform ""
+ :documentation "The value of the cookie. Will be URL-encoded
+when sent to the browser.")
+ (expires :initarg :expires
+ :initform nil
+ :accessor cookie-expires
+ :documentation "The time \(a universal time) when the
+cookie expires \(or NIL).")
+ (path :initarg :path
+ :initform nil
+ :accessor cookie-path
+ :documentation "The path this cookie is valid for \(or NIL).")
+ (domain :initarg :domain
+ :initform nil
+ :accessor cookie-domain
+ :documentation "The domain this cookie is valid for \(or NIL).")
+ (secure :initarg :secure
+ :initform nil
+ :accessor cookie-secure
+ :documentation "A generalized boolean denoting whether this
+cookie is a secure cookie.")
+ (http-only :initarg :http-only
+ :initform nil
+ :accessor cookie-http-only
+ :documentation "A generalized boolean denoting whether
+this cookie is a `HttpOnly' cookie.
+
+This is a Microsoft extension that has been implemented in Firefox as
+well. See <http://msdn2.microsoft.com/en-us/library/ms533046.aspx>."))
+ (:documentation "Each COOKIE objects describes one outgoing cookie."))
+
+(defmethod initialize-instance :around ((cookie cookie) &rest init-args)
+ "Ensure COOKIE has a correct slot-value for NAME."
+ (let ((name (getf init-args :name)))
+ (unless (http-token-p name)
+ (error "~S is not a legal name for a cookie." name)))
+ (call-next-method))
+
+(defun set-cookie* (cookie &optional (reply *reply*))
+ "Adds the COOKIE object COOKIE to the outgoing cookies of the
+REPLY object REPLY. If a cookie with the same name
+\(case-sensitive) already exists, it is replaced."
+ (let* ((name (cookie-name cookie))
+ (place (assoc name (cookies-out reply) :test #'string=)))
+ (cond
+ (place
+ (setf (cdr place) cookie))
+ (t
+ (push (cons name cookie) (cookies-out reply))
+ cookie))))
+
+(defun set-cookie (name &key (value "") expires path domain secure http-only (reply *reply*))
+ "Creates a cookie object from the parameters provided and adds
+it to the outgoing cookies of the REPLY object REPLY. If a cookie
+with the name NAME \(case-sensitive) already exists, it is
+replaced."
+ (set-cookie* (make-instance 'cookie
+ :name name
+ :value value
+ :expires expires
+ :path path
+ :domain domain
+ :secure secure
+ :http-only http-only)
+ reply))
+
+(defun cookie-date (universal-time)
+ "Converts UNIVERSAL-TIME to cookie date format."
+ (and universal-time
+ (rfc-1123-date universal-time)))
+
+(defmethod stringify-cookie ((cookie cookie))
+ "Converts the COOKIE object COOKIE to a string suitable for a
+'Set-Cookie' header to be sent to the client."
+ (format nil
+ "~A=~A~:[~;~:*; expires=~A~]~:[~;~:*; path=~A~]~:[~;~:*; domain=~A~]~:[~;; secure~]~:[~;; HttpOnly~]"
+ (cookie-name cookie)
+ (url-encode (format nil "~A" (cookie-value cookie)) +utf-8+)
+ (cookie-date (cookie-expires cookie))
+ (cookie-path cookie)
+ (cookie-domain cookie)
+ (cookie-secure cookie)
+ (cookie-http-only cookie)))
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/LICENSE.txt
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/LICENSE.txt 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/LICENSE.txt 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,9 @@
+The Hunchentoot logo (the file `hunchentoot.gif' in this directory)
+was created by Uwe von Loh and is available from his website at
+
+ http://www.htg1.de/hunchentoot/hunchentoot.html
+
+It is licensed under a `Creative Commons Attribution-Share Alike 2.0
+Germany License', see
+
+ http://creativecommons.org/licenses/by-sa/2.0/de/
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/LICENSE.txt
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/hunchentoot.gif
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/hunchentoot.gif
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/index.html
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/index.html 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/index.html 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,2614 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>HUNCHENTOOT - The Common Lisp web server formerly known as TBNL</title>
+ <style type="text/css">
+ pre { padding:5px; background-color:#e0e0e0 }
+ h3, h4 { text-decoration: underline; }
+ a { text-decoration: none; padding: 1px 2px 1px 2px; }
+ a:visited { text-decoration: none; padding: 1px 2px 1px 2px; }
+ a:hover { text-decoration: none; padding: 1px 1px 1px 1px; border: 1px solid #000000; }
+ a:focus { text-decoration: none; padding: 1px 2px 1px 2px; border: none; }
+ a.none { text-decoration: none; padding: 0; }
+ a.none:visited { text-decoration: none; padding: 0; }
+ a.none:hover { text-decoration: none; border: none; padding: 0; }
+ a.none:focus { text-decoration: none; border: none; padding: 0; }
+ a.noborder { text-decoration: none; padding: 0; }
+ a.noborder:visited { text-decoration: none; padding: 0; }
+ a.noborder:hover { text-decoration: none; border: none; padding: 0; }
+ a.noborder:focus { text-decoration: none; border: none; padding: 0; }
+ pre.none { padding:5px; background-color:#ffffff }
+ </style>
+</head>
+
+<body bgcolor=white>
+
+<h2><a href="http://www.htg1.de/hunchentoot/hunchentoot.html" title="Click here for the Hunchentoot logo" class=noborder><img align=top width=93 height=45 border=0 src="hunchentoot.gif"></a> HUNCHENTOOT - The Common Lisp web server formerly known as TBNL</h2>
+
+<blockquote>
+<br> <br><h3><a name=abstract class=none>Abstract</a></h3>
+
+Hunchentoot is a web server written in Common Lisp and at the same
+time a toolkit for building dynamic websites. As a
+stand-alone web server, Hunchentoot is capable of HTTP/1.1 chunking
+(both directions), persistent connections (keep-alive), and SSL, but
+it can also sit behind the
+popular <a href='http://httpd.apache.org/'>Apache</a> using
+Marc
+Battyani's <a
+href='http://www.fractalconcept.com/asp/html/mod_lisp.html'>mod_lisp</a>.
+
+<p>
+
+Hunchentoot provides facilities like automatic session handling (with
+and without cookies), logging (to Apache's log files or to a file in
+the file system), customizable error handling, and easy access to GET
+and POST parameters sent by the client. It does <em>not</em> include
+functionality to programmatically generate HTML output. For this task
+you can use any library you like, e.g. (shameless
+self-plug) <a href="http://weitz.de/cl-who/">CL-WHO</a>
+or <a href="http://weitz.de/html-template/">HTML-TEMPLATE</a>.
+
+<p>
+
+Hunchentoot talks with its front-end or with the client over TCP/IP
+sockets and uses multiprocessing to handle several requests at the
+same time. Therefore, it cannot be implemented completely
+in <a
+href="http://www.lispworks.com/documentation/HyperSpec/Front/index.htm">portable
+Common Lisp</a>. It currently works with
+<a href="http://www.lispworks.com/">LispWorks</a> (which is the main development and testing platform),
+<a href="http://www.cons.org/cmucl/">CMUCL</a> (with MP
+support), <a href="http://sbcl.sourceforge.net/">SBCL</a> (with
+Unicode and <a href="http://abstractstuff.livejournal.com/26811.html">thread</a> <a href="http://common-lisp.net/pipermail/tbnl-devel/2006-November/000780.html">support</a>),
+<a href="http://openmcl.clozure.com/">OpenMCL</a>,
+and <a href="http://www.franz.com/products/allegrocl/">Allegro Common
+Lisp</a>. (Note: You can use Hunchentoot with a version of SBCL
+without threads, for example on Windows, but this is not recommended
+except for development purposes.) Porting to other CL implementations
+shouldn't be too hard, see the files <code>port-xxx.lisp</code>
+and <code>unix-xxx.lisp</code> which comprise all the
+implementation-specific code.
+
+<p>
+
+Hunchentoot comes with a <a
+href="http://www.opensource.org/licenses/bsd-license.php">BSD-style
+license</a> so you can basically do with it whatever you want.
+<p>
+
+Hunchentoot is for example used by <a href="http://clutu.com/">clutu</a>, <a href="http://twitterbuzz.com/">TwitterBuzz</a>,
+<a href="http://www.jalat.com/">Jalat</a>, <a href="http://heikestephan.de/">Heike Stephan</a>,
+<a href="http://www.memetrics.com/">xOs</a>,
+and <a href="http://syseng.nist.gov/moss">the</a> <a href="http://syseng.nist.gov/se-interop">NIST</a>.
+
+<p>
+<font color=red>Download shortcut:</font> <a href="http://weitz.de/files/hunchentoot.tar.gz">http://weitz.de/files/hunchentoot.tar.gz</a>.
+</blockquote>
+
+<br> <br><h3><a class=none name="contents">Contents</a></h3>
+<ol>
+ <li><a href="#install">Download and installation</a>
+ <ol>
+ <li><a href='#proxy'>Hunchentoot behind a proxy</a>
+ <li><a href='#mod_lisp'>Hunchentoot behind mod_lisp</a>
+ </ol>
+ <li><a href="#mail">Support and mailing lists</a>
+ <li><a href="#example">Examples, tutorials, add-ons</a>
+ <li><a href="#reference">Function and variable reference</a>
+ <ol>
+ <li><a href='#servers'>Servers</a>
+ <li><a href='#handlers'>Handlers</a>
+ <li><a href='#requests'>Requests</a>
+ <li><a href='#replies'>Replies</a>
+ <li><a href='#cookies'>Cookies</a>
+ <li><a href='#sessions'>Sessions</a>
+ <li><a href='#log'>Logging and error handling</a>
+ <li><a href='#debug'>Debugging Hunchentoot applications</a>
+ <li><a href='#misc'>Miscellaneous</a>
+ </ol>
+ <li><a href="#ht-mp">The HUNCHENTOOT-MP package</a>
+ <li><a href="#performance">Performance</a>
+ <li><a href="#history">History</a>
+ <li><a href="#index">Symbol index</a>
+ <li><a href="#ack">Acknowledgements</a>
+</ol>
+
+<br> <br><h3><a name="install" class=none>Download and installation</a></h3>
+
+Hunchentoot depends on a couple of other Lisp libraries which you'll need
+to install first:
+<ul>
+ <li>Pierre R. Mai's <a href='http://www.cliki.net/md5'>MD5</a>,
+
+ <li>Kevin Rosenberg's <a href='http://www.cliki.net/cl-base64'>CL-BASE64</a>,
+
+ <li>Janis Dzerins' <a href='http://common-lisp.net/project/rfc2388/'>RFC2388</a>,
+
+ <li>David Lichteblau's <a href='http://common-lisp.net/project/cl-plus-ssl/'>CL+SSL</a> (unless you're using LispWorks),
+
+ <li><a href='http://www.cliki.net/ACL-COMPAT'>ACL-COMPAT</a> (for OpenMCL only),
+
+ <li>and my own <a href='http://weitz.de/flexi-streams/'>FLEXI-STREAMS</a> (0.12.0 or higher), <a href='http://weitz.de/chunga/'>Chunga</a>, <a href='http://weitz.de/cl-ppcre/'>CL-PPCRE</a>, and <a href='http://weitz.de/url-rewrite/'>URL-REWRITE</a> (plus <a href="http://weitz.de/cl-who/">CL-WHO</a> for the <a href="#example">example code</a>).
+</ul>
+Make sure to use the <em>newest</em> versions of all of these libraries (which might themselves depend on other libraries)!
+Note: You can compile Hunchentoot without SSL support - and thus without the need to have CL+SSL - if you add <code>:HUNCHENTOOT-NO-SSL</code> to <a href="http://www.lispworks.com/documentation/HyperSpec/Body/v_featur.htm"><code>*FEATURES*</code></a> <em>before</em> you compile it.
+<p>
+The preferred method to compile and load Hunchentoot is via <a href="http://www.cliki.net/asdf">ASDF</a>.
+<p>
+Hunchentoot together with this documentation can be downloaded
+from <a
+href="http://weitz.de/files/hunchentoot.tar.gz">http://weitz.de/files/hunchentoot.tar.gz</a>. The
+current version is 0.14.7. There's also a port
+for <a href="http://www.gentoo.org/proj/en/common-lisp/index.xml">Gentoo
+Linux</a> thanks to Matthew Kennedy.
+<p>
+A <a href="http://www.selenic.com/mercurial/wiki/">Mercurial</a>
+repository of older versions is available
+at <a
+href="http://arcanes.fr.eu.org/~pierre/2007/02/weitz/">http://arcanes.fr.eu.org/~pierre/2007/02/weitz/</a>
+thanks to Pierre Thierry.
+<p>
+Luís Oliveira maintains a <a href="http://darcs.net/">darcs</a>
+repository of Hunchentoot
+at <a
+href="http://common-lisp.net/~loliveira/ediware/">http://common-lisp.net/~loliveira/ediware/</a>.
+
+<h4><a name="proxy" class=none>Hunchentoot behind a proxy</a></h4>
+
+If you're feeling unsecure about exposing Hunchentoot to the wild,
+wild Internet or if your Lisp web application is part of a larger
+website, you can hide it behind
+a <a href="http://en.wikipedia.org/wiki/Proxy_server">proxy
+server</a>. One approach that I have used several times is to employ
+Apache's <a
+href="http://httpd.apache.org/docs/2.0/mod/mod_proxy.html">mod_proxy</a>
+module with a configuration that looks like this:
+<pre>
+<a href="http://httpd.apache.org/docs/2.0/mod/mod_proxy.html#proxypass" class=noborder>ProxyPass</a> /hunchentoot http://127.0.0.1:3000/hunchentoot
+<a href="http://httpd.apache.org/docs/2.0/mod/mod_proxy.html#proxypassreverse" class=noborder>ProxyPassReverse</a> /hunchentoot http://127.0.0.1:3000/hunchentoot
+</pre>
+This will tunnel all requests where the URI path begins with <code>"/hunchentoot"</code> to a (Hunchentoot) server listening on port 3000 on the same machine.
+<p>
+Of course, there are <a href="http://www.red-bean.com/pipermail/lispweb/2006-October/001342.html">several other</a> (more lightweight) web proxies that
+you could use instead of Apache.
+
+<h4><a name="mod_lisp" class=none>Hunchentoot behind mod_lisp</a></h4>
+
+You can also couple Hunchentoot more tightly with Apache
+using <a
+href='http://www.fractalconcept.com/asp/html/mod_lisp.html'>mod_lisp</a>.
+In this case, Apache will not send proxy requests to Hunchentoot, but
+communicate with it directly using a simple, line-based protocol. The
+downside of this approach is that it makes debugging harder. (Also,
+with mod_lisp,
+you <a
+href="http://common-lisp.net/pipermail/mod-lisp-devel/2006-October/000098.html">can't
+accept request bodies that use chunked encoding</a>. With the usual
+web browsers, this shouldn't be a problem, though.)
+<p>
+For this setup you need two things:
+
+<ul>
+ <li>The <a href='http://httpd.apache.org/'>Apache web server</a>. You can use either 1.3.x or 2.x. It is recommend that you use or build an Apache with <a href='http://httpd.apache.org/docs/dso.html'>DSO support</a>.
+
+ <li>The <a
+href='http://www.fractalconcept.com/asp/html/mod_lisp.html'>mod_lisp</a>
+Apache module by Marc Battyani. It is beyond the scope of this document to explain the
+details of how to install mod_lisp, but if your Apache has DSO support,
+it should suffice to issue a command like
+
+<pre>
+apxs -c -i -a mod_lisp.c
+</pre>
+
+as root (and afterwards restart Apache).
+<p>
+The newest version of mod_lisp is available from <a
+href="http://www.fractalconcept.com:8000/public/open-source/mod_lisp/">http://www.fractalconcept.com:8000/public/open-source/mod_lisp/</a>. For Apache 1.3.x you
+must use mod_lisp.c, for Apache 2.x you must use mod_lisp2.c, which is a reimplementation of Marc's mod_lisp by Chris Hanson.
+<p>
+You can get pre-compiled modules for the Win32 version of Apache 2 (but probably not the latest version) from <a href="http://www.fractalconcept.com:8000/public/open-source/mod_lisp/windows/">http://www.fractalconcept.com:8000/public/open-source/mod_lisp/windows/</a>. Put the file into Apache's <code>modules</code> folder and add the line
+<pre>
+LoadModule lisp_module modules/mod_lisp2.so
+</pre>
+to your <code>httpd.conf</code> file.
+
+</ul>
+
+Then you will have to configure Apache and mod_lisp to make them aware
+of Hunchentoot. First, in your Apache configuration file (usually
+called <code>httpd.conf</code>) add these lines
+
+<pre>
+<a name='LispServer' class=noborder>LispServer</a> 127.0.0.1 3000 "foo"
+
+<Location /hunchentoot>
+ SetHandler lisp-handler
+</Location>
+</pre>
+
+and afterwards restart Apache. This informs mod_lisp that there's a
+Lisp listening on port 3000 and named
+"foo" - you can of course use any other name or port or
+even put Hunchentoot on another physical machine. (In the latter case you'll
+have to replace <code>127.0.0.1</code> with the FQDN or IP address of
+this machine.)
+<p>
+The <code>Location/SetHandler</code> part means that every URL which
+starts with <code>/hunchentoot</code> will be handled by mod_lisp (and thus
+Hunchentoot) on this server. (Again, you can of course use other locations. See the
+Apache documentation for things like <em>virtual hosts</em> or
+directives like <code>LocationMatch</code>.)
+
+<p>
+
+To interface a Hunchentoot server with mod_lisp, you must start it
+with the <code>:MOD-LISP-P</code> keyword parameter
+of <a href="#start-server"><code>START-SERVER</code></a> set to a true
+value.
+
+<br> <br><h3><a name="mail" class=none>Support and mailing lists</a></h3>
+
+For questions, bug reports, feature requests, improvements, or patches
+please use
+the <a
+href="http://common-lisp.net/mailman/listinfo/tbnl-devel">tbnl-devel
+mailing list</a>. If you want to be notified about future releases
+subscribe to
+the <a
+href="http://common-lisp.net/mailman/listinfo/tbnl-announce">tbnl-announce
+mailing list</a>. These mailing lists were made available thanks to
+the services of <a href="http://common-lisp.net/">common-lisp.net</a>.
+You can <b>search</b> the devel mailing
+list <a
+href="http://google.com/coop/cse?cx=002927904911724867201%3A0l5rif_cxj0">here</a>
+(thanks to Tiarn�n � Corr�in).
+<p>
+If you want to send patches, please <a href="http://weitz.de/patches.html">read this first</a>.
+
+<br> <br><h3><a name="example" class=none>Examples, tutorials, add-ons</a></h3>
+
+Hunchentoot comes with an example website which you can use to see if
+it works and which should also demonstrate a couple of the things you
+can do with Hunchentoot. Use it as a kind of "Hello World" code to
+get yourself started.
+<p>
+To run the example,
+enter the following code into your listener:
+<pre>
+(<a class=noborder href="http://common-lisp.net/~mmommer/asdf-howto.shtml#sec11">asdf:oos</a> 'asdf:load-op :hunchentoot-test)
+(hunchentoot:<a class=noborder href="#start-server">start-server</a> :port 4242)
+</pre>
+You should now be able to point your browser
+at <code>http://localhost:4242/hunchentoot/test</code> and see
+something.
+<p>
+Here are some tutorials done by others:
+<ul>
+<li>Two <a href="http://myblog.rsynnott.com/2007/09/getting-started-with-hunchento.html">getting</a> <a href="http://myblog.rsynnott.com/2007/10/doing-more-with-hunchentoot-cl-server.ht…">started</a> articles by Robert Synnott.
+<li><a href="http://www.newartisans.com/blog_files/common.lisp.with.apache.php">Running Common Lisp behind Apache</a> by John Wiegley.
+<li>A <a href="http://www.lispcast.com/index.php/2007/10/lispcast-writing-a-simple-reddit-…">"LispCast"</a> by Eric Normand about writing a <a href="http://reddit.com/">Reddit</a> clone using Hunchentoot. Apparently the first part of a <a href="http://bc.tech.coop/blog/071028.html">series</a>.
+<li>A <a
+href="http://www.jalat.com/blogs/lisp?id=3">tutorial</a> for (an older version of) Hunchentoot by Asbjørn Bjørnstad.
+<li>A <a href="http://www.frank-buss.de/lisp/tbnl.html">TBNL
+tutorial</a> from Frank Buss. (Hunchentoot is not <a href="http://weitz.de/tbnl/">TBNL</a>, but the two
+are similar enough to make the tutorial worthwhile.)
+<li>
+For Win32, Bill Clementson
+<a
+href="http://bc.tech.coop/blog/041105.html">explains</a> how to set up Hunchentoot's predecessor <a href="http://weitz.de/tbnl/">TBNL</a> with
+Apache/mod_lisp. See also <a href="http://bc.tech.coop/blog/061013.html">http://bc.tech.coop/blog/061013.html</a>.
+</ul>
+Check the dates of these tutorials. Some of them might not be a
+perfect fit with the latest release of Hunchentoot. Also, the fact
+that these tutorials are listed here doesn't necessarily mean that I
+endorse them or think that they show idiomatic Lisp code. You'll have
+to decide yourself if they're helpful to you or not.
+</p>
+<p>
+Here is some software which extends Hunchentoot or is based on it:
+<ul>
+<li><a href="http://85.65.214.241/misc/ht-ajax.html">HT-AJAX</a> is
+an <a
+href="http://en.wikipedia.org/wiki/Ajax_%28programming%29">Ajax</a>
+framework for Hunchentoot by Ury Marshak.
+<li>Mac
+Chan <a
+href="http://common-lisp.net/pipermail/tbnl-devel/2007-May/001324.html">has
+ported <a href="http://lemonodor.com/">John
+Wiseman</a>'s <a
+href="http://www.lemonodor.com/archives/000128.html">Lisp Server
+Pages</a> to Hunchentoot.
+<li><a
+href="http://site.znain.com/dl/lisp/hunchentoot-dir-lister/">hunchentoot-dir-lister</a>
+is a directory listing addition for Hunchentoot by Dimitre Liotev.
+<li>Cyrus
+Harmon's <a
+href="http://cyrusharmon.org/blog/display?id=64">nuclblog</a> is a
+<a href="http://en.wikipedia.org/wiki/Blog">blog</a> engine which uses Hunchentoot.
+<li><a href="http://weitz.de/cl-webdav/">CL-WEBDAV</a> is a <a href="http://webdav.org/">WebDAV</a> server based on Hunchentoot.
+</ul>
+
+<br> <br><h3><a class=none name="reference">Function and variable reference</a></h3>
+
+<h4><a class=none name="servers">Servers</a></h4>
+
+If you want Hunchentoot to actually do something, you have
+to <a href="#start-server">start</a> a server. You can also run
+several servers in one image, each one listening to a different port.
+
+<p><br>[Function]
+<br><a class=none name="start-server"><b>start-server</b> <i><tt>&key</tt> port address name dispatch-table mod-lisp-p use-apache-log-p input-chunking-p read-timeout write-timeout setuid setgid ssl-certificate-file ssl-privatekey-file ssl-privatekey-password</i> => <i>server</i></a>
+
+<blockquote><br> Starts a Hunchentoot server instance and returns it.
+<code><i>port</i></code> ist the port the server will be listening on
+- the default is 80 (or 443 if SSL information is provided).
+If <code><i>address</i></code> is a string denoting an IP address,
+then the server only receives connections for that address. This must
+be one of the addresses associated with the machine and allowed values
+are host names such as <a class=none href="http://www.zappa.com/"><code>"www.zappa.com"</code></a> and address
+strings such as <a class=none href="http://72.3.247.29/"><code>"72.3.247.29"</code></a>.
+If <code><i>address</i></code> is <code>NIL</code>, then the server
+will receive connections to all IP addresses on the machine. This is
+the default.
+<p>
+<code><i>dispatch-table</i></code> can either be
+a <a href="#*dispatch-table*">dispatch table</a> which is to be used
+by this server or <code>NIL</code> which means that at request
+time <a href="#*meta-dispatcher*"><code>*META-DISPATCHER*</code></a>
+will be called to retrieve a dispatch table.
+<p>
+<code><i>name</i></code> should be a symbol which can be used to name
+the server. This name can utilized when
+defining <a href="#define-easy-handler">easy handlers</a>. The
+default name is an uninterned symbol as returned
+by <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_gensym.htm"><code>GENSYM</code></a>.
+<p>
+If <code><i>mod-lisp-p</i></code> is true (the default
+is <code>NIL</code>), the server will act as a back-end
+for <a href="#mod_lisp">mod_lisp</a>, otherwise it will be a
+stand-alone web server. If <code><i>use-apache-log-p</i></code> is
+true (which is the default), log messages will be written to the
+Apache log file - this parameter has no effect
+if <code><i>mod-lisp-p</i></code> is NIL.
+<p>
+If <code><i>input-chunking-p</i></code> is true (which is the
+default), the server will accept request bodies without
+a <code>Content-Length</code> header if the client uses chunked
+transfer encoding. If you want to use this feature behind mod_lisp,
+you should make sure that your combination of Apache and
+mod_lisp <a
+href="http://common-lisp.net/pipermail/mod-lisp-devel/2006-December/000104.html">can
+cope with that</a>.
+<p>
+<code><i>read-timeout</i></code> is the read timeout (in seconds) for
+the socket stream used by the server - the default value
+is <a
+href="#*default-read-timeout*"><code>*DEFAULT-READ-TIMEOUT*</code></a>.
+This parameter is ignored on OpenMCL. <code><i>write-timeout</i></code> is the write timeout (in
+seconds) for the socket stream used by the server - the default value
+is <a
+href="#*default-write-timeout*"><code>*DEFAULT-WRITE-TIMEOUT*</code></a>.
+This parameter is ignored on all implementations except for
+LispWorks 5.0 or higher and AllegroCL. You can use <code>NIL</code> in both
+cases to denote that you don't want a timeout.
+If <code><i>mod-lisp-p</i></code> is true, the timeouts are always set
+to <code>NIL</code>.
+<p>
+On Unix you can use <code><i>setuid</i></code>
+and <code><i>setgid</i></code> to change the UID and GID of the
+process directly after the server has been started. (You might want
+to do this if you're using a privileged port like 80.) <code><i>setuid</i></code> and
+<code><i>setgid</i></code> can be integers (the actual IDs) or strings
+(for the user and group name respectively).
+<p>
+If you want your server to use SSL, you must provide the pathname
+designator(s) <code><i>ssl-certificate-file</i></code> for the certificate file and
+optionally <code><i>ssl-privatekey-file</i></code> for the private key file, both files
+must be in PEM format. If you only provide the value for
+<code><i>ssl-certificate-file</i></code> it is assumed that both the
+certificate and the private key are in one file. If your private key
+needs a password you can provide it through
+the <code><i>ssl-privatekey-password</i></code> keyword argument. If
+you <em>don't</em> use LispWorks, the private key must not be
+associated with a password, and the certificate and the private key
+must be in separate files.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="stop-server"><b>stop-server</b> <i>server</i> => |</a>
+
+<blockquote><br>
+Stops a server started with <a href="#start-server"><code>START-SERVER</code></a>. <code><i>server</i></code> must be an object as returned by <a href="#start-server"><code>START-SERVER</code></a>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*server*"><b>*server*</b></a>
+
+<blockquote><br>
+During the execution of <a href="#handlers">dispatch functions and handlers</a> this variable
+is bound to the server object (as returned by <a href="#start-server"><code>START-SERVER</code></a>) which processes the request.
+</blockquote>
+
+<p><br>[Readers]
+<br><a class=none name="server-local-port"><b>server-local-port</b> <i>server</i> => <i>port</i></a>
+<br><a class=none name="server-address"><b>server-address</b> <i>server</i> => <i>address</i></a>
+
+<blockquote><br>
+These methods can be used to query a Hunchentoot server object. The values correspond to the <code><i>port</i></code> and <code><i>address</i></code> parameters of <a href="#start-server"><code>START-SERVER</code></a>.
+</blockquote>
+
+<p><br>[Accessor]
+<br><a class=none name="server-dispatch-table"><b>server-dispatch-table</b> <i>server</i> => <i>dispatch-table</i>
+<br><tt>(setf (</tt><b>server-dispatch-table</b> <i>server</i>) <i>new-value</i><tt>)</tt></a>
+
+<blockquote><br> These methods can be used to get and set
+the <a href="#*dispatch-table*">dispatch table</a> of a Hunchentoot
+server object. The value corresponds to
+the <code><i>dispatch-table</i></code> parameter
+of <a href="#start-server"><code>START-SERVER</code></a> and can be
+changed at runtime. It can be set to NIL which means that the server
+doesn't have its own dispatch table
+and <a href="#*meta-dispatcher*"><code>*META-DISPATCHER*</code></a> should be
+called instead.
+</blockquote>
+
+<p><br>[Accessor]
+<br><a class=none name="server-name"><b>server-name</b> <i>server</i> => <i>name</i>
+<br><tt>(setf (</tt><b>server-name</b> <i>server</i>) <i>new-value</i><tt>)</tt></a>
+<blockquote><br> These methods can be used to get and set the name of a server
+which must be a symbol.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*default-read-timeout*"><b>*default-read-timeout*</b></a>
+
+<blockquote><br> The default value for the <code><i>read-timeout</i></code> keyword
+argument to <a href="#start-server"><code>START-SERVER</code></a>. The initial value is 20 (seconds).
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*default-write-timeout*"><b>*default-write-timeout*</b></a>
+
+<blockquote><br> The default value for the <code><i>write-timeout</i></code> keyword
+argument to <a href="#start-server"><code>START-SERVER</code></a>. The initial value is 20 (seconds).
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*cleanup-interval*"><b>*cleanup-interval*</b></a>
+
+<blockquote><br>
+Should be <code>NIL</code> or a positive integer. The system calls
+<a href="#*cleanup-function*"><code>*CLEANUP-FUNCTION*</code></a> whenever <a href="#*cleanup-interval*"><code>*CLEANUP-INTERVAL*</code></a> new worker threads have
+been created unless the value is <code>NIL</code>. The initial value is 100.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*cleanup-function*"><b>*cleanup-function*</b></a>
+
+<blockquote><br>
+The function (with no arguments) which is called if <a href="#*cleanup-interval*"><code>*CLEANUP-INTERVAL*</code></a> is not <code>NIL</code>.
+The initial value is a function which calls
+<code>(<a href="http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-166.htm">HCL</a>:<a href="http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-212.htm"><code>MARK-AND-SWEEP</code></a> 2)</code> on LispWorks and does nothing on other Lisps.
+<p>
+On LispWorks this is necessary because each <em>worker</em> (which is
+created to handle an incoming http request and which dies afterwards
+unless the connection is persistent) is a Lisp process and LispWorks
+creates processes in generation 2.
+<p>
+Note that you can also set this value to <code>NIL</code> and tune
+LispWork's GC yourself, using for
+example <a
+href="http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-180.htm"><code>COLLECT-GENERATION-2</code></a>.
+</blockquote>
+
+<h4><a class=none name="handlers">Handlers</a></h4>
+
+Hunchentoot handles each incoming request dynamically depending on the
+contents of a global <em>dispatch table</em>. The details can be found
+below. (See the file <code>test/test.lisp</code> for examples.)
+
+<p><br>[Special variable]
+<br><a class=none name="*dispatch-table*"><b>*dispatch-table*</b></a>
+
+<blockquote><br>
+
+The return value of the initial value of <a href="#*meta-dispatcher*"><code>*META-DISPATCHER*</code></a>.
+<p>
+This is a list of <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function…">function
+designators</a> for <em>dispatch functions</em> each of which should
+be a function of one argument which accepts a <a
+href='#requests'><code>REQUEST</code></a> object and, depending on
+this object, should either return a <em>handler</em> to handle the
+request or <code>NIL</code> which means that the next dispatcher will
+be queried. A <em>handler</em> is a designator for a function with no
+arguments which usually returns a string or an array of octets to be sent to the client as
+the body of the http reply. (Note that if you use symbols as function
+designators, you can redefine your handler functions without the need
+to change the dispatch functions.) See <a href='#replies'>the section
+about replies</a> for more about what handlers can do.
+<p>
+The dispatchers in a dispatch table are tried in turn
+until one of them returns a handler. If this doesn't happen, Hunchentoot will
+return a 404 status code (Not Found) to the client.
+<p>
+The initial value of <code>*DISPATCH-TABLE*</code> is a list which
+just contains the symbol <a
+href='#default-dispatcher'><code>DEFAULT-DISPATCHER</code></a>.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="default-dispatcher"><b>default-dispatcher</b> <i>request</i> => <i>handler</i></a>
+
+<blockquote><br>
+
+This is a function which will always unconditionally return the value of <a
+href='#*default-handler*'><code>*DEFAULT-HANDLER*</code></a>. It is intended to be the last element of <a
+href='#*dispatch-table*'><code>*DISPATCH-TABLE*</code></a>.
+
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*default-handler*"><b>*default-handler*</b></a>
+
+<blockquote><br>
+
+This variable holds the handler which is always returned by <a
+href='#default-dispatcher'><code>DEFAULT-DISPATCHER</code></a>. The
+default value is a function which unconditonally shows a short Hunchentoot
+info page.
+
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*meta-dispatcher*"><b>*meta-dispatcher*</b></a>
+
+<blockquote><br> The value of this variable should be a function of
+one argument. It is called with the current Hunchentoot server
+instance (unless the server has <a href="#server-dispatch-table">its
+own dispatch table</a>) and must return a dispatch table suitable for
+Hunchentoot. The initial value is a function which always
+unconditionally returns
+<a href="#*dispatch-table*"><code>*DISPATCH-TABLE*</code></a>.
+<p>
+This can obviously be used to assign different dispatch tables to
+different servers (and is useless if you only have one server).
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="create-prefix-dispatcher"><b>create-prefix-dispatcher</b> <i>prefix handler</i> => <i>dispatch-fn</i></a>
+
+<blockquote><br>
+
+A convenience function which will return a dispatcher that returns <code><i>handler</i></code> whenever the path part of the request URI starts with the string <code><i>prefix</i></code>.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="create-regex-dispatcher"><b>create-regex-dispatcher</b> <i>regex handler</i> => <i>dispatch-fn</i></a>
+
+<blockquote><br>
+
+A convenience function which will return a dispatcher that returns <code><i>handler</i></code> whenever the path part of the request URI matches the <a href='http://weitz.de/cl-ppcre/'>CL-PPCRE</a> regular expression <code><i>regex</i></code> (which can be a string, an s-expression, or a scanner).
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="handle-static-file"><b>handle-static-file</b> <i>path <tt>&optional</tt> content-type</i> => <i>nil</i></a>
+
+<blockquote><br>
+Sends the file denote by the pathname designator
+<code><i>path</i></code> with content type
+<code><i>content-type</i></code> to the client. Sets the necessary handlers. In particular the function employs
+<a href="#handle-if-modified-since"><code>HANDLE-IF-MODIFIED-SINCE</code></a>.
+<p>
+If <code><i>content-type</i></code> is <code>NIL</code> the function
+tries to determine the correct content type from the file's suffix or
+falls back to <code>"application/octet-stream"</code> as a last resort.
+<p>
+Note that this function
+calls <a href="#send-headers"><code>SEND-HEADERS</code></a>
+internally, so after you've called it, the headers are sent and the
+return value of your handler is ignored.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="create-static-file-dispatcher-and-handler"><b>create-static-file-dispatcher-and-handler</b> <i>uri path <tt>&optional</tt> content-type</i> => <i>dispatch-fn</i></a>
+
+<blockquote><br>
+
+A convenience function which will return a dispatcher that dispatches
+to a handler which emits the file denoted by the pathname designator
+<code><i>path</i></code> with content type
+<code><i>content-type</i></code>
+if the <a href='#script-name'><code>SCRIPT-NAME</code></a> of the
+request matches the string <code><i>uri</i></code>. Uses <a href="#handle-static-file"><code>HANDLE-STATIC-FILE</code></a> internally.
+<p>
+If <code><i>content-type</i></code> is <code>NIL</code> the function tries to determine the correct content type from the file's suffix
+or falls back to <code>"application/octet-stream"</code> as a last resort.
+<a href='#*default-content-type*'><code>*DEFAULT-CONTENT-TYPE*</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="create-folder-dispatcher-and-handler"><b>create-folder-dispatcher-and-handler</b> <i>uri-prefix base-path <tt>&optional</tt> content-type</i> => <i>dispatch-fn</i></a>
+
+<blockquote><br>
+Creates and returns a dispatch function which will dispatch to a
+handler function which emits the file relative to <code><i>base-path</i></code> that is
+denoted by the URI of the request relative to <code><i>uri-prefix</i></code>. <code><i>uri-prefix</i></code>
+must be a string ending with a slash, <code><i>base-path</i></code> must be a pathname
+designator for an existing directory.
+Uses <a href="#handle-static-file"><code>HANDLE-STATIC-FILE</code></a> internally.
+<p>
+If <code><i>content-type</i></code> is <em>not</em> <code>NIL</code>,
+it will be used as a the content type for all files in the folder.
+Otherwise (which is the default) the content type of each file will be determined <a href="#handle-static-file">as usual</a>.
+</blockquote>
+
+<p><br>[Generic function]
+<br><a class=none name="dispatch-request"><b>dispatch-request</b> <i>dispatch-table</i> => <i>result</i></a>
+
+<blockquote><br>
+This is a generic function so users can customize its behaviour. Look at the source code for details.
+</blockquote>
+
+<p><br>[Macro]
+<br><a class=none name="define-easy-handler"><b>define-easy-handler</b> <i>description lambda-list [[declaration* | documentation]] form*</i></a>
+
+<blockquote><br>
+
+Defines a handler as if
+by <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/m_defun.htm"><code>DEFUN</code></a>
+and optionally registers it with a URI so that it will be found
+by <a
+href="#dispatch-easy-handlers"><code>DISPATCH-EASY-HANDLERS</code></a>.
+<p>
+<code><i>description</i></code> is either a symbol <code><i>name</i></code> or a list matching the
+<a href="http://www.lispworks.com/documentation/HyperSpec/Body/03_de.htm">destructuring lambda list</a>
+
+<pre>
+ (name &key uri server-names default-parameter-type default-request-type).
+</pre>
+
+<code><i>lambda-list</i></code> is a list the elements of which are either a symbol
+<code><i>var</i></code> or a list matching the destructuring lambda list
+
+<pre>
+ (var &key real-name parameter-type init-form request-type).
+</pre>
+
+The resulting handler will be a Lisp function with the
+name <code><i>name</i></code> and keyword parameters named by
+the <code><i>var</i></code> symbols. Each <code><i>var</i></code>
+will be bound to the value of the GET or POST parameter
+called <code><i>real-name</i></code> (a string) before the body of the
+function is executed. If <code><i>real-name</i></code> is not
+provided, it will be computed by <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_stg_up.htm#string-d…">downcasing</a> the symbol name
+of <code><i>var</i></code>.
+<p>
+If <code><i>uri</i></code> (which is evaluated) is provided, then it must be a string or
+a <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function…">function
+designator</a> for a unary function. In this case,
+the handler will be returned by <a href="#dispatch-easy-handlers"><code>DISPATCH-EASY-HANDLERS</code></a>, if <code><i>uri</i></code> is a
+string and the <a href="#script-name">script name</a> of the current request is <code><i>uri</i></code>, or if <code><i>uri</i></code> designates a
+function and applying this function to the <a href="#*request*">current <code>REQUEST</code> object</a>
+returns a true value.
+<p>
+
+<code><i>server-names</i></code> (which is evaluated) can be a list of
+symbols which means that the handler will only be returned
+by <a
+href="#dispatch-easy-handlers"><code>DISPATCH-EASY-HANDLERS</code></a>
+in servers which have one of these names
+(see <a
+href="#server-name"><code>SERVER-NAME</code></a>). <code><i>server-names</i></code>
+can also be the symbol <code>T</code> which means that the handler
+will be returned
+by <a
+href="#dispatch-easy-handlers"><code>DISPATCH-EASY-HANDLERS</code></a>
+in <em>every</em> server.
+<p>
+Whether the GET or POST parameter (or both) will be taken into
+consideration, depends on <code><i>request-type</i></code> which can
+be <code>:GET</code>, <code>:POST</code>, <code>:BOTH</code>, or <code>NIL</code>. In the last case, the value of
+<code><i>default-request-type</i></code> (the default of which
+is <code>:BOTH</code>) will be used.
+<p>
+The value of <code><i>var</i></code> will usually be a string (unless
+it resulted from a <a href="#upload">file upload</a> in which case it won't be converted at
+all), but if <code><i>parameter-type</i></code> (which is evaluated)
+is provided, the string will be converted to another Lisp type by the
+following rules:
+<p>
+If the corresponding GET or POST parameter wasn't provided by the
+client, <code><i>var</i></code>'s value will be <code>NIL</code>. If <code><i>parameter-type</i></code> is <code>'STRING</code>,
+<code><i>var</i></code>'s value remains as is. If <code><i>parameter-type</i></code> is <code>'INTEGER</code> and the
+parameter string consists solely of decimal digits, <code><i>var</i></code>'s value will be
+the corresponding integer, otherwise <code>NIL</code>. If <code><i>parameter-type</i></code> is
+<code>'KEYWORD</code>, <code><i>var</i></code>'s value will be the
+keyword obtained
+by <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_intern.htm">interning</a>
+the <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_stg_up.htm#string-u…">upcased</a> parameter string into
+the <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/11_abc.htm">keyword
+package</a>. If <code><i>parameter-type</i></code>
+is <code>'CHARACTER</code> and the parameter string is of length
+one, <code><i>var</i></code>'s value will be the single character of
+this string, otherwise <code>NIL</code>.
+If <code><i>parameter-type</i></code>
+is <code>'BOOLEAN</code>, <code><i>var</i></code>'s value will always
+be <code>T</code> (unless it is <code>NIL</code> by the first rule
+above, of course). If <code><i>parameter-type</i></code> is any other
+atom, it is supposed to be
+a <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function…">function
+designator</a> for a unary function which will be called to
+convert the string to something else.
+<p>
+Those were the rules for <em>simple</em> parameter types, but
+<code><i>parameter-type</i></code> can also be a list starting with one of the symbols
+<code>LIST</code>, <code>ARRAY</code>, or <code>HASH-TABLE</code>.
+The second value of the list must always be a simple parameter type as
+in the last paragraph - we'll call it the <em>inner type</em> below.
+<p>
+In the case of <code>'LIST</code>, all GET/POST parameters
+called <code><i>real-name</i></code> will be collected, converted to
+the inner type as by the rules above, and assembled into a list which
+will be the value of
+<code><i>var</i></code>.
+<p>
+In the case of <code>'ARRAY</code>, all GET/POST parameters which have
+a name like the result of
+
+<pre>
+ (format nil "~A[~A]" real-name n)
+</pre>
+
+where <code><i>n</i></code> is a non-negative integer, will be
+assembled into an array where the <code><i>n</i></code>th element will
+be set accordingly, after conversion to the inner type. The array,
+which will become the value of <code><i>var</i></code>, will be big
+enough to hold all matching parameters, but not bigger. Array
+elements not set as described above will be <code>NIL</code>. Note
+that <code>VAR</code> will always be bound to an array, which may be
+empty, so it will never be <code>NIL</code>, even if no appropriate
+GET/POST parameters are found.
+<p>
+The full form of a <code>'HASH-TABLE</code> parameter type is
+
+<pre>
+ (hash-table inner-type key-type test-function),
+</pre>
+
+but <code><i>key-type</i></code> and <code><i>test-function</i></code>
+can be left out in which case they default to <code>'STRING</code>
+and <code>'EQUAL</code>, respectively. For this parameter type, all
+GET/POST parameters which have a name like the result of
+
+<pre>
+ (format nil "~A{~A}" real-name key)
+</pre>
+
+(where <code><i>key</i></code> is a string that doesn't contain curly brackets) will
+become the values (after conversion to <code><i>inner-type</i></code>) of a hash
+table with test function <code><i>test-function</i></code> where <code><i>key</i></code> (after
+conversion to <code><i>key-type</i></code>) will be the corresponding key. Note that
+<code><i>var</i></code> will always be bound to a hash table, which
+may be empty, so it will never be <code>NIL</code>, even if no
+appropriate GET/POST parameters are found.
+<p>
+To make matters even more complicated, the three compound parameter
+types also have an abbreviated form - just one of the
+symbols <code>LIST</code>, <code>ARRAY</code>,
+or <code>HASH-TABLE</code>. In this case, the inner type will default
+to <code>'STRING</code>.
+<p>
+If <code><i>parameter-type</i></code> is not provided
+or <code>NIL</code>, <code><i>default-parameter-type</i></code> (the
+default of which is <code>'STRING</code>) will be used instead.
+<p>
+If the result of the computations above would be
+that <code><i>var</i></code> would be bound to <code>NIL</code>,
+then <code><i>init-form</i></code> (if provided) will be evaluated
+instead, and <code><i>var</i></code> will be bound to the result of
+this evaluation.
+<p>
+Handlers built with this macro are constructed in such a way that the
+resulting Lisp function is useful even outside of Hunchentoot. Specifically,
+all the parameter computations above will only happen
+if <a href="#*request*"><code>*REQUEST*</code></a> is bound, i.e. if
+we're within a Hunchentoot request. Otherwise, <code><i>var</i></code> will
+always be bound to the result of
+evaluating <code><i>init-form</i></code> unless a corresponding
+keyword argument is provided.
+<p>
+The <a href="#example">example code</a> that comes with Hunchentoot contains an
+example which demonstrates some of the features
+of <a
+href="#define-easy-handler"><code>DEFINE-EASY-HANDLER</code></a>.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="dispatch-easy-handlers"><b>dispatch-easy-handlers</b> <i>request</i> => <i>handler</i></a>
+
+<blockquote><br>
+
+This is a dispatcher which returns the appropriate handler defined
+with <a
+href="#define-easy-handler"><code>DEFINE-EASY-HANDLER</code></a>, if
+there is one. The newest handlers are checked
+first. <a
+href="#define-easy-handler"><code>DEFINE-EASY-HANDLER</code></a> makes
+sure that there's always only one handler per name and one per URI.
+URIs are compared
+by <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_equal.htm"><code>EQUAL</code></a>,
+so anonymous functions won't be recognized as being identical.
+
+</blockquote>
+
+<h4><a class=none name="requests">Requests</a></h4>
+
+When a request comes in, Hunchentoot creates a <code>REQUEST</code> object
+which is available to the <a href="#handlers">handler</a> via the
+special variable <a href='#*request*'><code>*REQUEST*</code></a>. This object holds
+all the information available about the request and can be queried
+with the functions described in this chapter. Note that the internal
+structure of <code>REQUEST</code> objects should be considered opaque and may change
+in future releases of Hunchentoot.
+<p>
+In all of the functions below, the default value
+for <code><i>request</i></code> (which is either an optional or a
+keyword argument) is the value of <a href='#*request*'><code>*REQUEST*</code></a>,
+i.e. handlers will usually not need to provide this argument when
+calling the function.
+<p>
+(Some of the function names in this section might seem a bit strange.
+This is because they were initially chosen to be similar to
+environment variables in CGI scripts.)
+
+<p><br>[Special variable]
+<br><a class=none name="*request*"><b>*request*</b></a>
+
+<blockquote><br>
+
+Holds the current <code>REQUEST</code> object.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="host"><b>host</b> <i><tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+
+Returns the value of the incoming <code>Host</code> http header.
+(This corresponds to
+the environment variable <code>HTTP_HOST</code> in CGI
+scripts.)
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="request-method"><b>request-method</b> <i><tt>&optional</tt> request</i> => <i>keyword</i></a>
+
+<blockquote><br>
+
+Returns the request method as a keyword, i.e. something like <code>:POST</code>. (This corresponds to the environment
+variable <code>REQUEST_METHOD</code> in CGI scripts.)
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="request-uri"><b>request-uri</b> <i><tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+
+Returns the URI for <code><i>request</i></code>. Note that this not the full URI but only the part behind the
+scheme and authority components, so that if the user has typed <code>http://user:password@www.domain.com/xxx/frob.html?foo=bar</code> into his browser, this function will return <code>"/xxx/frob.html?foo=bar"</code>.
+(This corresponds to
+the environment variable <code>REQUEST_URI</code> in CGI
+scripts.)
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="script-name"><b>script-name</b> <i><tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+
+Returns the file name (or path) component of the URI
+for <code><i>request</i></code>, i.e. the part of the string returned
+by <a href="#request-uri"><code>REQUEST-URI</code></a> in front of the
+first question mark (if any).
+(This corresponds to
+the environment variable <code>SCRIPT_NAME</code> in CGI
+scripts.)
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="query-string"><b>query-string</b> <i><tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+
+Returns the query component of the URI
+for <code><i>request</i></code>, i.e. the part of the string returned
+by <a href="#request-uri"><code>REQUEST-URI</code></a> behind the
+first question mark (if any).
+(This corresponds to
+the environment variable <code>QUERY_STRING</code> in CGI
+scripts.) See also <a href="#get-parameter"><code>GET-PARAMETER</code></a> and <a href="#get-parameters"><code>GET-PARAMETERS</code></a>.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="get-parameter"><b>get-parameter</b> <i>name <tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+Returns the value of the GET parameter (as provided via the request URI) named by the string <code><i>name</i></code> as a string (or <code>NIL</code> if there ain't no GET parameter with this name). Note that only the first value will be returned if the client provided more than one GET parameter with the name <code><i>name</i></code>. See also <a href="#get-parameters"><code>GET-PARAMETERS</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="get-parameters"><b>get-parameters</b> <i><tt>&optional</tt> request</i> => <i>alist</i></a>
+
+<blockquote><br>
+Returns an <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#alist">alist</a> of all GET parameters (as provided via the request URI). The <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#car">car</a> of each element of this list is the parameter's name while the <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#cdr">cdr</a> is its value (as a string). The elements of this list are in the same order as they were within the request URI. See also <a href="#get-parameter"><code>GET-PARAMETER</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="post-parameter"><b>post-parameter</b> <i>name <tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+Returns the value of the POST parameter (as provided in the request's body) named by the string <code><i>name</i></code>. Note that only the first value will be returned if the client provided more than one POST parameter with the name <code><i>name</i></code>.
+This value will usually be a string (or <code>NIL</code> if there ain't no POST parameter with this name). If, however, the browser sent a <a class=none name="upload">file</a> through a <a href="http://www.faqs.org/rfcs/rfc2388.html"><code>multipart/form-data</code></a> form, the value of this function is a three-element list
+<pre>
+(path file-name content-type)
+</pre>
+where <code><i>path</i></code> is a pathname denoting the place were the uploaded file was stored, <code><i>file-name</i></code> (a string) is the file name sent by the browser, and <code><i>content-type</i></code> (also a string) is the content type sent by the browser. The file denoted by <code><i>path</i></code> will be deleted after the request has been handled - you have to move or copy it somewhere else if you want to keep it.
+<p>
+POST parameters will only be computed if the content type of the request body was <code>multipart/form-data</code>
+or <code>application/x-www-form-urlencoded</code>.
+Although this function is called <code>POST-PARAMETER</code>, you can instruct Hunchentoot to compute these parameters for other request methods by setting <a href="#*methods-for-post-parameters*"><code>*METHODS-FOR-POST-PARAMETERS*</code></a>.
+<p>
+See also <a href="#post-parameters"><code>POST-PARAMETERS</code></a> and <a href="#*tmp-directory*"><code>*TMP-DIRECTORY*</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="post-parameters"><b>post-parameters</b> <i><tt>&optional</tt> request</i> => <i>alist</i></a>
+
+<blockquote><br>
+Returns an <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#alist">alist</a> of all POST parameters (as provided via the request's body). The <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#car">car</a> of each element of this list is the parameter's name while the <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#cdr">cdr</a> is its value. The elements of this list are in the same order as they were within the request's body.
+<p>
+See also <a href="#post-parameter"><code>POST-PARAMETER</code></a>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*methods-for-post-parameters*"><b>*methods-for-post-parameters*</b></a>
+
+<blockquote><br> A list of the request method types (as keywords) for
+which Hunchentoot will try to compute <a href="#post-parameter">"POST"
+parameters</a>. The default is the list with the single
+element <code>:POST</code>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*file-upload-hook*"><b>*file-upload-hook*</b></a>
+
+<blockquote><br> If this is not <code>NIL</code>, it should be
+a <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function…">designator</a>
+for a unary function which will be called with a pathname for each
+file which is <a href="#upload">uploaded</a> to Hunchentoot. The pathname
+denotes the temporary file to which the uploaded file is written. The
+hook is called directly <em>before</em> the file is created. At this
+point, <a href="#*request*"><code>*REQUEST*</code></a> is already
+bound to the current <code>REQUEST</code> object, but obviously you
+can't access the post parameters yet.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="raw-post-data"><b>raw-post-data</b> <tt>&key</tt> <i>request external-format force-text force-binary want-stream</i> => <i>raw-body-or-stream</i></a>
+
+<blockquote><br> Returns the content sent by the client in the request
+body if there was any (unless the content type
+was <code>multipart/form-data</code> in which case <code>NIL</code>
+is returned). By default, the result is a string if the type of
+the <code>Content-Type</code> <a
+href="http://www.faqs.org/rfcs/rfc1590.html">media type</a>
+is <code>"text"</code>, and a vector of octets otherwise. In the case
+of a string, the external format to be used to decode the content will
+be determined from the <code>charset</code> parameter sent by the
+client (or
+otherwise <a
+href="#*hunchentoot-default-external-format*"><code>*HUNCHENTOOT-DEFAULT-EXTERNAL-FORMAT*</code></a>
+will be used).
+<p>
+You can also provide an external format explicitly (through
+<code><i>external-format</i></code>) in which case the result will
+unconditionally be a string. Likewise, you can provide a true value
+for <code><i>force-text</i></code> which will force Hunchentoot to act
+as if the type of the media type had been <code>"text"</code>
+(with <code><i>external-format</i></code> taking precedence if
+provided). Or you can provide a true value
+for <code><i>force-binary</i></code> which means that you want a
+vector of octets at any rate. (If both
+<code><i>force-text</i></code> and <code><i>force-binary</i></code>
+are true, an error will be signaled.)
+<p>
+If, however, you provide a true value
+for <code><i>want-stream</i></code>, the other parameters are ignored
+and you'll get the content (flexi) stream to read from it yourself.
+It is then your responsibility to read the correct amount of data,
+because otherwise you won't be able to return a response to the
+client. The stream will have
+its <a href="http://weitz.de/flexi-streams/#flexi-streams">octet
+position</a> set to <code>0</code>. If the client provided
+a <code>Content-Length</code> header, the stream will also have
+a
+corresponding <a href="http://weitz.de/flexi-streams/#flexi-streams">bound</a>,
+so no matter whether the client used chunked encoding or not, you can
+always read until EOF.
+<p>
+If the content type of the request
+was <code>multipart/form-data</code>
+or <code>application/x-www-form-urlencoded</code>, the content has
+been read by Hunchentoot already and you can't read from the stream
+anymore.
+<p>
+You can call <a href="#raw-post-data"><code>RAW-POST-DATA</code></a>
+more than once per request, but you can't mix calls which have
+different values for <code><i>want-stream</i></code>.
+<p>
+Note that this function is slightly misnamed because a client can send
+content even if the request method is not POST.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="parameter"><b>parameter</b> <i>name <tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+Returns the value of the GET or POST parameter named by the string <code><i>name</i></code> as a string (or <code>NIL</code> if there ain't no parameter with this name). If both a GET and a POST parameter with the name <code><i>name</i></code> exist, the GET parameter will be returned. See also <a href="#get-parameter"><code>GET-PARAMETER</code></a> and <a href="#post-parameter"><code>POST-PARAMETER</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="header-in"><b>header-in</b> <i>name <tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br> Returns the incoming header named by the
+keyword <code><i>name</i></code> as a string (or <code>NIL</code> if
+there ain't no header with this name). Note that this queries the
+headers sent to Hunchentoot by the client <em>or</em> by mod_lisp. In
+the latter case this may not only include the incoming http headers
+but also
+some <a href='http://www.fractalconcept.com/asp/debug'>headers sent by
+mod_lisp</a>.
+<p>For backwards compatibility, <code><i>name</i></code>
+can also be a string which is matched case-insensitively. See
+also <a href="#headers-in"><code>HEADERS-IN</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="headers-in"><b>headers-in</b> <i><tt>&optional</tt> request</i> => <i>alist</i></a>
+
+<blockquote><br>
+Returns an <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#alist">alist</a> of all incoming headers. The <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#car">car</a> of each element of this list is the headers's name (a Lisp keyword) while the <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#cdr">cdr</a> is its value (as a string). There's no guarantee about the order of this list. See also <a href="#header-in"><code>HEADER-IN</code></a> and the remark about incoming headers there.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="authorization"><b>authorization</b> <i><tt>&optional</tt> request</i> => <i>user, password</i></a>
+
+<blockquote><br>
+Returns as two values the user and password (if any) from the incoming <code>Authorization</code> http header. Returns <code>NIL</code> if there is no such header.
+</blockquote>
+
+
+<p><br>[Function]
+<br><a class=none name="remote-addr"><b>remote-addr</b> <i><tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+
+Returns the IP address (as a string) of the client which sent the
+request. (This corresponds to the environment
+variable <code>REMOTE_ADDR</code> in CGI scripts.) See
+also <a href="#real-remote-addr"><code>REAL-REMOTE-ADDR</code></a>.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="remote-port"><b>remote-port</b> <i><tt>&optional</tt> request</i> => <i>number</i></a>
+
+<blockquote><br>
+
+Returns the IP port (as a number) of the client which sent the request.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="real-remote-addr"><b>real-remote-addr</b> <i><tt>&optional</tt> request</i> => <i>string{, list}</i></a>
+
+<blockquote><br>
+
+Returns the value of the
+incoming <a
+href="http://en.wikipedia.org/wiki/XFF"><code>X-Forwarded-For</code></a>
+http header as the second value in the form of a list of IP addresses
+and the first element of this list as the first value if this header
+exists. Otherwise returns the value
+of <a href="#remote-addr"><code>REMOTE-ADDR</code></a> as the only
+value.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="server-addr"><b>server-addr</b> <i><tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+
+Returns the IP address (as a string) where the request came in. (This
+corresponds to the environment variable <code>SERVER_ADDR</code> in
+CGI scripts.)
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="server-port"><b>server-port</b> <i><tt>&optional</tt> request</i> => <i>number</i></a>
+
+<blockquote><br>
+
+Returns the IP port (as a number) where the request came in.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="server-protocol"><b>server-protocol</b> <i><tt>&optional</tt> request</i> => <i>keyword</i></a>
+
+<blockquote><br>
+
+Returns the version of the http protocol which is used by the client as a Lisp keyword - this is usually either <code>:HTTP/1.0</code> or <code>:HTTP/1.1</code>.
+(This corresponds to the environment
+variable <code>SERVER_PROTOCOL</code> in CGI scripts.)
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="mod-lisp-id"><b>mod-lisp-id</b> <i><tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+
+Returns the 'Server ID' sent by mod_lisp. This corresponds to the
+third parameter in the "<a
+href='#LispServer'>LispServer</a>" directive in Apache's
+configuration file and can be interesting if you deploy several different
+Apaches or Hunchentoot instances at once. Returns <code>NIL</code> in stand-alone servers.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="ssl-session-id"><b>ssl-session-id</b> <i><tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+
+Returns Apache's SSL session ID if it exists. Note that SSL sessions aren't related to <a href='#sessions'>Hunchentoot sessions</a>.
+(This corresponds to
+the environment variable <code>SSL_SESSION_ID</code> in CGI
+scripts.) Returns <code>NIL</code> in stand-alone servers.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="user-agent"><b>user-agent</b> <i><tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+
+Returns the value of the incoming <code>User-Agent</code> http header.
+(This corresponds to
+the environment variable <code>HTTP_USER_AGENT</code> in CGI
+scripts.)
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="referer"><b>referer</b> <i><tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+
+Returns the value of the incoming <code>Referer</code> (sic!) http header.
+(This corresponds to
+the environment variable <code>HTTP_REFERER</code> in CGI
+scripts.)
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="cookie-in"><b>cookie-in</b> <i>name <tt>&optional</tt> request</i> => <i>string</i></a>
+
+<blockquote><br>
+Returns the value of the incoming cookie named by the string <code><i>name</i></code> (or <code>NIL</code> if there ain't no cookie with this name). See also <a href="#cookies-in"><code>COOKIES-IN</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="cookies-in"><b>cookies-in</b> <i><tt>&optional</tt> request</i> => <i>alist</i></a>
+
+<blockquote><br>
+Returns an <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#alist">alist</a> of all incoming cookies. The <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#car">car</a> of each element of this list is the cookie's name while the <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#cdr">cdr</a> is the cookie's value. See also <a href="#cookie-in"><code>COOKIE-IN</code></a>.
+</blockquote>
+
+<p><br>[Accessor]
+<br><a class=none name="aux-request-value"><b>aux-request-value</b> <i>symbol <tt>&optional</tt> request</i> => <i>value, present-p</i>
+<br><tt>(setf (</tt><b>aux-request-value</b> <i>symbol <tt>&optional</tt> request</i>) <i>new-value</i><tt>)</tt></a>
+
+<blockquote><br>
+This accessor can be used to associate arbitrary data with the the <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#symbol">symbol</a> <code><i>symbol</i></code> in the <code>REQUEST</code>
+object <code><i>request</i></code>.
+<code><i>present-p</i></code> is <em>true</em> if such data was found,
+otherwise <code>NIL</code>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="delete-aux-request-value"><b>delete-aux-request-value</b> <i>symbol <tt>&optional</tt> request</i> => |</a>
+
+<blockquote><br>
+Completely removes any data associated with the <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#symbol">symbol</a> <code><i>symbol</i></code> from the <code>REQUEST</code>
+object <code><i>request</i></code>. Note that this is different from
+using <a href="#aux-request-value"><code>AUX-REQUEST-VALUE</code></a> to set the data to <code>NIL</code>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="recompute-request-parameters"><b>recompute-request-parameters</b> <i><tt>&key</tt> request external-format</i> => |</a>
+
+<blockquote><br> Recomputes the GET and POST parameters for
+the <code>REQUEST</code> object
+<code><i>request</i></code>. This only makes sense if you've changed
+the external format and with POST parameters it will only work if the
+request body was sent with
+the <code>application/x-www-form-urlencoded</code> content type.
+<p>
+The default value for
+<code><i>external-format</i></code> is <a
+href="#*hunchentoot-default-external-format*"><code>*HUNCHENTOOT-DEFAULT-EXTERNAL-FORMAT*</code></a>.
+See <code>test/test.lisp</code> for an example.
+</blockquote>
+
+<h4><a class=none name="replies">Replies</a></h4>
+
+It is the responsibility of a <a href='#handlers'>handler</a> function to prepare the reply for the client. This is done by
+
+<ul>
+ <li>returning a string or an array of octets which will be the reply's body and
+ <li>manipulating a <code>REPLY</code> object which will be described in this section.
+</ul>
+
+For each request there's one <code>REPLY</code> object which is accessible
+to the handler via the
+special variable <a href='#*reply*'>*REPLY*</a>. This object holds
+all the information available about the reply and can be accessed
+with the functions described in this chapter. Note that the internal
+structure of <code>REPLY</code> objects should be considered opaque and may change
+in future releases of Hunchentoot.
+<p>
+In all of the functions below, the default value
+for the optional argument <code><i>reply</i></code> is the value of <a href='#*reply*'>*REPLY*</a>,
+i.e. handlers will usually not need to provide this argument when
+calling the function.
+<p>
+While Hunchentoot's preferred way of sending data to the client is the
+one described above (i.e. the handler returns the whole payload as a
+string or an array of octets) you can, if you really need to (for
+example for large content bodies), get a stream you can write to
+directly. This is achieved by first setting
+up <a href="#*reply*"><code>*REPLY*</code></a> and then
+calling <a href="#send-headers"><code>SEND-HEADERS</code></a>. Note
+that in this case the usual <a href="#log">error handling</a> is
+disabled. See the file <code>test/test.lisp</code> for an example.
+
+<p><br>[Special variable]
+<br><a class=none name="*reply*"><b>*reply*</b></a>
+
+<blockquote><br>
+
+Holds the current <code>REPLY</code> object.
+
+</blockquote>
+
+<p><br>[Accessor]
+<br><a class=none name="header-out"><b>header-out</b> <i>name <tt>&optional</tt> reply</i> => <i>string</i>
+<br><tt>(setf (</tt><b>header-out</b> <i>name <tt>&optional</tt> reply</i>) <i>new-value</i><tt>)</tt></a>
+
+<blockquote><br>
+
+<code>HEADER-OUT</code> returns the outgoing http header named by the
+keyword <code><i>name</i></code> if there is one,
+otherwise <code>NIL</code>. <code>SETF</code>
+of <code>HEADER-OUT</code> changes the current value of the header
+named <code><i>name</i></code>. If no header
+named <code><i>name</i></code> exists it is created. For backwards
+compatibility, <code><i>name</i></code> can also be a string in which
+case the association between a header and its name is
+case-insensitive.
+<p>
+Note that the
+headers <code>Set-Cookie</code>, <code>Content-Length</code>,
+and <code>Content-Type</code> cannot be queried
+by <code>HEADER-OUT</code> and <em>must not</em> be set
+by <code>SETF</code> of <code>HEADER-OUT</code>. Also, there are a
+couple of "technical" headers like <code>Connection</code>
+or <code>Transfer-Encoding</code> that you're not supposed to set
+yourself. If in doubt, consult the source code or ask on
+the <a href="#mail">mailing list</a>.
+<p>
+See also <a href="#headers-out"><code>HEADERS-OUT</code></a>, <a href="#content-type"><code>CONTENT-TYPE</code></a>, <a href="#content-length"><code>CONTENT-LENGTH</code></a>, <a href="#cookies-out"><code>COOKIES-OUT</code></a>, and <a href="#cookie-out"><code>COOKIE-OUT</code></a>.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="headers-out"><b>headers-out</b> <i><tt>&optional</tt> request</i> => <i>alist</i></a>
+
+<blockquote><br>
+Returns an <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#alist">alist</a> of all outgoing http parameters (except for <code>Set-Cookie</code>, <code>Content-Length</code>,
+and <code>Content-Type</code>). The <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#car">car</a> of each element of this list is the headers's name while the <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#cdr">cdr</a> is its value. This alist should not be manipulated directly, use <code>SETF</code> of <a href="#header-out"><code>HEADER-OUT</code></a> instead.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="cookie-out"><b>cookie-out</b> <i>name <tt>&optional</tt> reply</i> => <i>cookie</i></a>
+
+<blockquote><br>
+Returns the outgoing cookie named by the string <code><i>name</i></code> (or <code>NIL</code> if there ain't no cookie with this name). See also <a href="#cookies-out"><code>COOKIES-OUT</code></a> and <a href='#cookies'>the section about cookies</a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="cookies-out"><b>cookies-out</b> <i><tt>&optional</tt> reply</i> => <i>alist</i></a>
+
+<blockquote><br>
+Returns an <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#alist">alist</a> of all outgoing cookies. The <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#car">car</a> of each element of this list is the cookie's name while the <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#cdr">cdr</a> is the cookie itself. See also <a href="#cookie-out"><code>COOKIE-OUT</code></a> and <a href='#cookies'>the section about cookies</a>.
+</blockquote>
+
+<p><br>[Accessor]
+<br><a class=none name="return-code"><b>return-code</b> <i><tt>&optional</tt> reply</i> => <i>number</i>
+<br><tt>(setf (</tt><b>return-code</b> <i><tt>&optional</tt> reply</i>) <i>new-value</i><tt>)</tt></a>
+
+<blockquote><br>
+
+<code>RETURN-CODE</code> returns the http return code of the
+reply, <code>SETF</code> of <code>RETURN-CODE</code> changes it. The
+return code of each <code>REPLY</code> object is initially set to <a
+href="#+http-ok+"><code>+HTTP-OK+</code></a>.
+
+</blockquote>
+
+<p><br>[Accessor]
+<br><a class=none name="content-type"><b>content-type</b> <i><tt>&optional</tt> reply</i> => <i>string</i>
+<br><tt>(setf (</tt><b>content-type</b> <i><tt>&optional</tt> reply</i>) <i>new-value</i><tt>)</tt></a>
+
+<blockquote><br>
+
+<code>CONTENT-TYPE</code> returns the
+outgoing <code>Content-Type</code> http header. <code>SETF</code>
+of <code>CONTENT-TYPE</code> changes the current value of this header. The content type of each <code>REPLY</code> object is initially set to the value of <a href="#*default-content-type*"><code>*DEFAULT-CONTENT-TYPE*</code></a>.
+</blockquote>
+
+<p><br>[Accessor]
+<br><a class=none name="content-length"><b>content-length</b> <i><tt>&optional</tt> reply</i> => <i>length</i>
+<br><tt>(setf (</tt><b>content-length</b> <i><tt>&optional</tt> reply</i>) <i>new-value</i><tt>)</tt></a>
+
+<blockquote><br>
+
+<code>CONTENT-LENGTH</code> returns the outgoing
+<code>Content-Length</code> http header. <code>SETF</code> of
+<code>CONTENT-LENGTH</code> changes the current value of this
+header. The content length of each <code>REPLY</code> object is
+initially set to <code>NIL</code>. If you leave it like that,
+Hunchentoot will automatically try to compute the correct value
+using <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_length.htm"><code>LENGTH</code></a>.
+If you set the value yourself, you <em>must</em> make sure that it's
+the correct length of the body in <em>octets</em> (not in characters).
+In this case, Hunchentoot will use the value as is which can lead to
+erroneous behaviour if it is wrong - so, use at your own risk.
+<p>
+Note that setting this value explicitly doesn't mix well with <a
+href="#*rewrite-for-session-urls*">URL rewriting</a>.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="send-headers"><b>send-headers</b> => <i>stream</i></a>
+
+<blockquote><br>
+Sends the initial status line and all headers as determined by
+the <code>REPLY</code> object <a href="#*reply*"><code>*REPLY*</code></a>. Returns a <a href="http://weitz.de/flexi-streams/#flexi-streams">flexi stream</a> to which the body of
+the reply can be written. Once this function has been called,
+further changes to <a href="#*reply*"><code>*REPLY*</code></a> don't have any effect. Also,
+<a href="#log">automatic handling of errors</a> (i.e. sending the
+corresponding status code to the browser, etc.) is turned off for this
+request. Likewise, functions
+like <a href="#redirect"><code>REDIRECT</code></a> or throwing
+to <a href="#handler-done"><code>HANDLER-DONE</code></a>
+won't have the desired effect once the headers are sent.
+<p>
+If your handlers return the full body as a string or as an array of
+octets, you should <em>not</em> call this function. If a handler
+calls <a href="#send-headers"><code>SEND-HEADERS</code></a>, its return
+value is ignored.
+<p>
+See also <a href="#reply-external-format"><code>REPLY-EXTERNAL-FORMAT</code></a>.
+</blockquote>
+
+<p><br>[Accessor]
+<br><a class=none name="reply-external-format"><b>reply-external-format</b> <i><tt>&optional</tt> reply</i> => <i>external-format</i>
+<br><tt>(setf (</tt><b>reply-external-format</b> <i><tt>&optional</tt> reply</i>) <i>new-value</i><tt>)</tt></a>
+
+<blockquote><br>
+
+Gets and sets the external format of the <code>REPLY</code>
+object <code><i>reply</i></code>. This external format is used when
+character content is written to the client after the headers have been
+sent. In particular, it is the external format of the stream returned by <a href="#send-headers"><code>SEND-HEADERS</code></a> (but of course you can change it because it's a <a href="http://weitz.de/flexi-streams/#flexi-streams">flexi stream</a>).
+<p>The initial value for each request is the value
+of <a
+href="#*hunchentoot-default-external-format*"><code>*HUNCHENTOOT-DEFAULT-EXTERNAL-FORMAT*</code></a>.
+
+</blockquote>
+
+<p><br>[Constants]
+<br><a class=none name='+http-continue+'><b>+http-continue+</b></a>
+<br><a class=none name='+http-switching-protocols+'><b>+http-switching-protocols+</b></a>
+<br><a class=none name='+http-ok+'><b>+http-ok+</b></a>
+<br><a class=none name='+http-created+'><b>+http-created+</b></a>
+<br><a class=none name='+http-accepted+'><b>+http-accepted+</b></a>
+<br><a class=none name='+http-non-authoritative-information+'><b>+http-non-authoritative-information+</b></a>
+<br><a class=none name='+http-no-content+'><b>+http-no-content+</b></a>
+<br><a class=none name='+http-reset-content+'><b>+http-reset-content+</b></a>
+<br><a class=none name='+http-partial-content+'><b>+http-partial-content+</b></a>
+<br><a class=none name='+http-multi-status+'><b>+http-multi-status+</b></a>
+<br><a class=none name='+http-multiple-choices+'><b>+http-multiple-choices+</b></a>
+<br><a class=none name='+http-moved-permanently+'><b>+http-moved-permanently+</b></a>
+<br><a class=none name='+http-moved-temporarily+'><b>+http-moved-temporarily+</b></a>
+<br><a class=none name='+http-see-other+'><b>+http-see-other+</b></a>
+<br><a class=none name='+http-not-modified+'><b>+http-not-modified+</b></a>
+<br><a class=none name='+http-use-proxy+'><b>+http-use-proxy+</b></a>
+<br><a class=none name='+http-temporary-redirect+'><b>+http-temporary-redirect+</b></a>
+<br><a class=none name='+http-bad-request+'><b>+http-bad-request+</b></a>
+<br><a class=none name='+http-authorization-required+'><b>+http-authorization-required+</b></a>
+<br><a class=none name='+http-payment-required+'><b>+http-payment-required+</b></a>
+<br><a class=none name='+http-forbidden+'><b>+http-forbidden+</b></a>
+<br><a class=none name='+http-not-found+'><b>+http-not-found+</b></a>
+<br><a class=none name='+http-method-not-allowed+'><b>+http-method-not-allowed+</b></a>
+<br><a class=none name='+http-not-acceptable+'><b>+http-not-acceptable+</b></a>
+<br><a class=none name='+http-proxy-authentication-required+'><b>+http-proxy-authentication-required+</b></a>
+<br><a class=none name='+http-request-time-out+'><b>+http-request-time-out+</b></a>
+<br><a class=none name='+http-conflict+'><b>+http-conflict+</b></a>
+<br><a class=none name='+http-gone+'><b>+http-gone+</b></a>
+<br><a class=none name='+http-length-required+'><b>+http-length-required+</b></a>
+<br><a class=none name='+http-precondition-failed+'><b>+http-precondition-failed+</b></a>
+<br><a class=none name='+http-request-entity-too-large+'><b>+http-request-entity-too-large+</b></a>
+<br><a class=none name='+http-request-uri-too-large+'><b>+http-request-uri-too-large+</b></a>
+<br><a class=none name='+http-unsupported-media-type+'><b>+http-unsupported-media-type+</b></a>
+<br><a class=none name='+http-requested-range-not-satisfiable+'><b>+http-requested-range-not-satisfiable+</b></a>
+<br><a class=none name='+http-expectation-failed+'><b>+http-expectation-failed+</b></a>
+<br><a class=none name='+http-failed-dependency+'><b>+http-failed-dependency+</b></a>
+<br><a class=none name='+http-internal-server-error+'><b>+http-internal-server-error+</b></a>
+<br><a class=none name='+http-not-implemented+'><b>+http-not-implemented+</b></a>
+<br><a class=none name='+http-bad-gateway+'><b>+http-bad-gateway+</b></a>
+<br><a class=none name='+http-service-unavailable+'><b>+http-service-unavailable+</b></a>
+<br><a class=none name='+http-gateway-time-out+'><b>+http-gateway-time-out+</b></a>
+<br><a class=none name='+http-version-not-supported+'><b>+http-version-not-supported+</b></a>
+
+<blockquote><br>
+The values of these constants are 100, 101, 200, 201, 202, 203, 204, 205, 206, 207, 300, 301, 302, 303, 304, 305, 307, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 424, 500, 501, 502, 503, 504, and 505. See <a href="#return-code"><code>RETURN-CODE</code></a>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name='*default-content-type*'><b>*default-content-type*</b></a>
+
+<blockquote><br>
+The value of this variable is used to initialize the content type of each <code>REPLY</code> object. Its initial value is <code>"text/html; charset=iso-8859-1"</code>. See <a href="#content-type"><code>CONTENT-TYPE</code></a>.
+</blockquote>
+
+<h4><a class=none name="cookies">Cookies</a></h4>
+
+Outgoing cookies are stored in the request's <code>REPLY</code> object (see <a href="#cookie-out"><code>COOKIE-OUT</code></a> and <a href="#cookies-out"><code>COOKIES-OUT</code></a>). They are CLOS objects defined like this:
+
+<pre>
+(defclass cookie ()
+ ((name :initarg :name
+ :reader <a class=noborder name='cookie-name'>cookie-name</a>
+ :type string
+ :documentation "The name of the cookie - a string.")
+ (value :initarg :value
+ :accessor <a class=noborder name='cookie-value'>cookie-value</a>
+ :initform ""
+ :documentation "The value of the cookie. Will be URL-encoded when sent to the browser.")
+ (expires :initarg :expires
+ :initform nil
+ :accessor <a class=noborder name='cookie-expires'>cookie-expires</a>
+ :documentation "The time (a universal time) when the cookie expires (or NIL).")
+ (path :initarg :path
+ :initform nil
+ :accessor <a class=noborder name='cookie-path'>cookie-path</a>
+ :documentation "The path this cookie is valid for (or NIL).")
+ (domain :initarg :domain
+ :initform nil
+ :accessor <a class=noborder name='cookie-domain'>cookie-domain</a>
+ :documentation "The domain this cookie is valid for (or NIL).")
+ (secure :initarg :secure
+ :initform nil
+ :accessor <a class=noborder name='cookie-secure'>cookie-secure</a>
+ :documentation "A generalized boolean denoting whether this is a secure cookie.")
+ (http-only :initarg :http-only
+ :initform nil
+ :accessor <a class=noborder name='cookie-http-only'>cookie-http-only</a>
+ :documentation "A generalized boolean denoting whether this is a <a href="http://msdn2.microsoft.com/en-us/library/ms533046.aspx">HttpOnly</a> cookie.")))
+</pre>
+
+The <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_r.htm#reader">reader</a> <a href="#cookie-name"><code>COOKIE-NAME</code></a> and
+the <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#accessor">accessors</a>
+<a href="#cookie-value"><code>COOKIE-VALUE</code></a>, <a
+href="#cookie-expires"><code>COOKIE-EXPIRES</code></a>, <a
+href="#cookie-path"><code>COOKIE-PATH</code></a>, <a
+href="#cookie-domain"><code>COOKIE-DOMAIN</code></a>, <a
+href="#cookie-secure"><code>COOKIE-SECURE</code></a>, and <a
+href="#cookie-http-only"><code>COOKIE-HTTP-ONLY</code></a> are all exported
+from the <code>HUNCHENTOOT</code> package.
+
+<p><br>[Function]
+<br><a class=none name="set-cookie"><b>set-cookie</b> <i>name <tt>&key</tt> value expires path domain secure http-only reply</i> => <i>cookie</i></a>
+
+<blockquote><br> Creates a <code>COOKIE</code> object from the
+parameters provided to this function and adds it to the outgoing
+cookies of the <a href='#replies'><code>REPLY</code>
+object</a> <code><i>reply</i></code>. If a cookie with the same name
+(case-sensitive) already exists, it is replaced. The default
+for <code><i>reply</i></code> is <a
+href="#*reply*"><code>*REPLY*</code></a>. The default for <code><i>value</i></code> is the empty string.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="set-cookie*"><b>set-cookie*</b> <i>cookie <tt>&optional</tt> reply</i> => <i>cookie</i></a>
+
+<blockquote><br> Adds the <code>COOKIE</code>
+object <code><i>cookie</i></code> to the outgoing cookies of the <a
+href='#replies'><code>REPLY</code>
+object</a> <code><i>reply</i></code>. If a cookie with the same name
+(case-sensitive) already exists, it is replaced. The default for <code><i>reply</i></code> is <a href="#*reply*"><code>*REPLY*</code></a>.
+</blockquote>
+
+<h4><a class=none name="sessions">Sessions</a></h4>
+
+Hunchentoot supports <em>sessions</em>: Once a Hunchentoot page has
+called <a href="#start-session"><code>START-SESSION</code></a>,
+Hunchentoot uses either cookies or (if the client doesn't send the
+cookies back) <a href="#*rewrite-for-session-urls*">rewrites URLs</a>
+to keep track of this client, i.e. to provide a kind of 'state' for
+the stateless http protocol. The session associated with the client is
+an opaque CLOS object which can be used to store arbitrary data
+between requests.
+<p>
+Hunchentoot makes some reasonable effort to prevent eavesdroppers from
+hijacking sessions (see below), but this should not be considered
+really secure. Don't store sensitive data in sessions and rely
+solely on the session mechanism as a safeguard against malicious users
+who want to get at this data!
+<p>
+For each request there's one <code>SESSION</code> object which is accessible
+to the handler via the
+special variable <a href='#*session*'><code>*SESSION*</code></a>. This object holds
+all the information available about the session and can be accessed
+with the functions described in this chapter. Note that the internal
+structure of <code>SESSION</code> objects should be considered opaque and may change
+in future releases of Hunchentoot.
+<p>
+Sessions are automatically verified for validity and age when
+the <a href='#requests'><code>REQUEST</code> object</a> is instantiated, i.e. if <a
+href='#*session*'><code>*SESSION*</code></a> is not <code>NIL</code> then this
+session is valid (as far as Hunchentoot is concerned) and not too old. Old sessions are <a href="#session-gc">automatically removed</a>.
+
+<p><br>[Special variable]
+<br><a class=none name="*session*"><b>*session*</b></a>
+
+<blockquote><br>
+
+Holds the current <code>SESSION</code> object (if any) or <code>NIL</code>.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="start-session"><b>start-session</b> => <i>session</i></a>
+
+<blockquote><br> Returns <a
+href="#*session*"><code>*SESSION*</code></a> if it
+isn't <code>NIL</code>, otherwise creates a new <code>SESSION</code>
+object and returns it.
+</blockquote>
+
+<p><br>[Accessor]
+<br><a class=none name="session-value"><b>session-value</b> <i>symbol <tt>&optional</tt> session</i> => <i>value, present-p</i>
+<br><tt>(setf (</tt><b>session-value</b> <i>symbol <tt>&optional</tt> session</i>) <i>new-value</i><tt>)</tt></a>
+
+<blockquote><br>
+This accessor can be used to associate arbitrary data with the the <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#symbol">symbol</a> <code><i>symbol</i></code> in the <code>SESSION</code>
+object <code><i>session</i></code>.
+<code><i>present-p</i></code> is <em>true</em> if such data was found,
+otherwise <code>NIL</code>. The default value
+for <code><i>session</i></code> is <a
+href="#*session*"><code>*SESSION*</code></a>.
+<p>
+If <code>SETF</code> of <code>SESSION-VALUE</code> is called with <code><i>session</i></code> being <code>NIL</code> then a session is automatically instantiated with <a href="#start-session"><code>START-SESSION</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="delete-session-value"><b>delete-session-value</b> <i>symbol <tt>&optional</tt> session</i> => |</a>
+
+<blockquote><br>
+Completely removes any data associated with the <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#symbol">symbol</a> <code><i>symbol</i></code> from the <code>SESSION</code>
+object <code><i>session</i></code>. Note that this is different from
+using <a href="#session-value"><code>SESSION-VALUE</code></a> to set the data to <code>NIL</code>.
+The default value
+for <code><i>session</i></code> is <a
+href="#*session*"><code>*SESSION*</code></a>.
+</blockquote>
+
+
+<p><br>[Function]
+<br><a class=none name="remove-session"><b>remove-session</b> <i>session</i> => |</a>
+
+<blockquote><br>
+Completely removes the session <code><i>session</i></code> from Hunchentoot's internal session database. See also <a href="#*session-removal-hook*"><code>*SESSION-REMOVAL-HOOK*</code></a>.
+</blockquote>
+
+
+<p><br>[Function]
+<br><a class=none name="reset-sessions"><b>reset-sessions</b> => |</a>
+
+<blockquote><br>
+This function unconditionally invalidates and destroys <em>all</em> sessions immediately.
+</blockquote>
+
+
+<p><br>[Function]
+<br><a class=none name="session-cookie-value"><b>session-cookie-value</b> <i>session</i> => <i>string</i></a>
+
+<blockquote><br>
+Returns a unique string that's associated with
+the <code>SESSION</code> object <code><i>session</i></code>. This
+string is sent to the browser as a cookie value or as a GET parameter,
+</blockquote>
+
+
+<p><br>[Function]
+<br><a class=none name="session-counter"><b>session-counter</b> <i>session</i> => <i>count</i></a>
+
+<blockquote><br>
+Returns the number of times (requests) the <code>SESSION</code> object <code><i>session</i></code> has been used.
+</blockquote>
+
+
+
+<p><br>[Accessor]
+<br><a class=none name="session-max-time"><b>session-max-time</b> <i>session</i> => <i>seconds</i>
+<br><tt>(setf (</tt><b>session-max-time</b> <i>session</i>) <i>seconds</i><tt>)</tt></a>
+
+<blockquote><br> This gets or sets the maximum time (in seconds)
+the <code>SESSION</code> object <code><i>session</i></code> should be
+valid before it's invalidated: If a request associated with this
+session comes in and the last request for the same session was more
+than <code><i>seconds</i></code> seconds ago
+than the session is deleted and a new one is started for this client. The default value is determined by <a href="#*session-max-time*"><code>*SESSION-MAX-TIME*</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="session-remote-addr"><b>session-remote-addr</b> <i>session</i> => <i>address</i></a>
+
+<blockquote><br> Returns the 'real' remote address (see <a
+href="#real-remote-addr"><code>REAL-REMOTE-ADDR</code></a>) of the
+client for which the <code>SESSION</code>
+object <code><i>session</i></code> was initiated.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="session-user-agent"><b>session-user-agent</b> <i>session</i> => <i>address</i></a>
+
+<blockquote><br> Returns the 'User-Agent' http header (see <a
+href="#user-agent"><code>USER-AGENT</code></a>) of the
+client for which the <code>SESSION</code>
+object <code><i>session</i></code> was initiated.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*use-remote-addr-for-sessions*"><b>*use-remote-addr-for-sessions*</b></a>
+
+<blockquote><br>
+
+If this value is <em>true</em> (the default is <code>NIL</code>) then
+the 'real' remote address (see <a
+href="#real-remote-addr"><code>REAL-REMOTE-ADDR</code></a>) of the
+client will be encoded into the session identifier, i.e. if this value
+changes on the client side, the session will automatically be
+invalidated.
+<p>
+Note that this is not secure, because it's obviously not very hard to
+fake an <code>X_FORWARDED_FOR</code> header. On the other hand,
+relying on the remote address (see <a
+href="#remote-addr"><code>REMOTE-ADDR</code></a>) of the client isn't
+an ideal solution either, because some of your users may connect
+through http proxies and the proxy they use may change during the
+session. But then again, some proxies don't
+send <code>X_FORWARDED_FOR</code> headers anyway. Sigh...
+
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*use-user-agent-for-sessions*"><b>*use-user-agent-for-sessions*</b></a>
+
+<blockquote><br> If this value is <em>true</em> (which is the default)
+then the 'User-Agent' http header (see <a
+href="#user-agent"><code>USER-AGENT</code></a>) of the client will be
+encoded into the session identifier, i.e. if this value changes on the
+client side the session will automatically be invalidated.
+<p>
+While this is intended to make the life of malicious users harder, it
+might affect legitimate users as well: I've seen this http
+header change with certain browsers when the Java plug-in was used.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*rewrite-for-session-urls*"><b>*rewrite-for-session-urls*</b></a>
+
+<blockquote><br> If this value is <em>true</em> (which is the default)
+then content bodies sent by Hunchentoot will be rewritten
+(using <a href='http://weitz.de/url-rewrite/'>URL-REWRITE</a>) such
+that GET parameters for session handling are appended to all relevant
+URLs. This only happens, though, if the body's content type (see <a
+href="#content-type"><code>CONTENT-TYPE</code></a>) starts
+with one of the strings in <a href="#*content-types-for-url-rewrite*"><code>*CONTENT-TYPES-FOR-URL-REWRITE*</code></a> and unless the client has already sent a cookie named <a href="#*session-cookie-name*"><code>*SESSION-COOKIE-NAME*</code></a>.
+<p>
+Note that the function which rewrites the body doesn't understand
+Javascript, so you have to take care of URLs in Javascript code yourself.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*content-types-for-url-rewrite*"><b>*content-types-for-url-rewrite*</b></a>
+
+<blockquote><br>
+This is a list of strings (the initial value is
+<code>("text/html" "application/xhtml+xml")</code>) the
+content-type of an outgoing body is compared with if <a
+href="#*rewrite-for-session-urls*"><code>*REWRITE-FOR-SESSION-URLS*</code></a>
+is true. If the content-type starts with one of these strings, then
+url-rewriting will happen, otherwise it won't.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*session-cookie-name*"><b>*session-cookie-name*</b></a>
+
+<blockquote><br>
+
+This is the name that is used for the session-related cookie or GET
+parameter sent to the client. Its default value
+is <code>"hunchentoot-session"</code>. Note that changing this name while
+Hunchentoot is running will invalidate existing sessions.
+
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*session-removal-hook*"><b>*session-removal-hook*</b></a>
+
+<blockquote><br>
+The value of this variable should be a function of one argument, a <code>SESSION</code> object. This function is called directly before the session is destroyed, either by <a href="#reset-sessions"><code>RESET-SESSIONS</code></a>, by <a href="#remove-session"><code>REMOVE-SESSION</code></a>, or when it's invalidated because it's too old.
+
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*session-max-time*"><b>*session-max-time*</b></a>
+
+<blockquote><br>
+The default time (in seconds) after which a session times out - see <a href="#session-max-time"><code>SESSION-MAX-TIME</code></a>. This value is initially set to 1800.
+</blockquote>
+
+<p><br>[Macro]
+<br><a class=none name="do-sessions"><b>do-sessions</b> <i>(var</i> <tt>&optional</tt> <i>result-form) statement*</i> => <i>result</i></a>
+
+<blockquote><br>
+
+Executes the statements with <code><i>var</i></code> bound to each
+existing <code>SESSION</code> object consecutively. An implicit block
+named <code>NIL</code> surrounds the body of this macro. Returns the
+values returned by <code><i>result-form</i></code> unless
+<code>RETURN</code> is executed. The scope of the binding of
+<code><i>var</i></code> does <em>not</em> include
+<code><i>result-form</i></code>.
+
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*session-gc-frequency*"><b>*session-gc-frequency*</b></a>
+
+<blockquote><br>
+A session garbage collection (see <a href="#session-gc"><code>SESSION-GC</code></a>) will happen every
+<a
+href="#*session-gc-frequency*"><code>*SESSION-GC-FREQUENCY*</code></a>
+requests (counting only requests which use sessions) if the value of
+this variable is not <code>NIL</code>. It's default value is 50.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="session-gc"><b>session-gc</b> => |</a>
+
+<blockquote><br>
+Deletes sessions which are too old - see
+<a href="#session-too-old-p"><code>SESSION-TOO-OLD-P</code></a>.
+Usually, you don't call this function directly -
+see <a
+href="#*session-gc-frequency*"><code>*SESSION-GC-FREQUENCY*</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="session-too-old-p"><b>session-too-old-p</b> <i>session</i> => generalized-boolean</a>
+
+<blockquote><br> Returns a true value if the <code>SESSION</code>
+object <code><i>session</i></code> is <a href="#session-max-time">too old</a> and would be deleted
+during the next <a href="#session-gc">session GC</a>. You don't
+have to check this manually for sessions
+in <a href="#*session*"><code>*SESSION*</code></a>, but it might be
+useful if you want to <a href="#do-sessions">loop through all
+sessions</a>.
+</blockquote>
+
+
+<h4><a class=none name="log">Logging and error handling</a></h4>
+
+Hunchentoot provides facilities for writing to Apache's error log
+file (when using the mod_lisp front-end) or for logging to an arbitrary file in the file system. Note that, due to the nature of mod_lisp, Apache log mesages don't appear immediately but only after all data has been sent from Hunchentoot to Apache/mod_lisp.
+<p>
+Furthermore, all errors happening within a <a href='#handlers'>handler</a> which are not
+caught by the handler itself are handled by Hunchentoot - see details below.
+
+<p><br>[Accessor]
+<br><a class=none name="log-file"><b>log-file</b> => <i>pathname</i>
+<br><tt>(setf (</tt><b>log-file</b>) <i>pathspec</i><tt>)</tt></a>
+
+<blockquote><br>
+The function <code>LOG-FILE</code> returns a pathname designating the log file which is currently used (unless log messages are forwarded to Apache). This destination for log messages can be changed with <code>(SETF LOG-FILE)</code>. The initial location of the log file is implementation-dependent.
+</blockquote>
+
+<p><br>[Generic function]
+<br><a class=none name="log-message"><b>log-message</b> <i>log-level format</i> <tt>&rest</tt> <i>args</i> => |</a>
+
+<blockquote><br> Schedules a message for the Apache log file or writes
+it directly to <a href="#log-file">the current log file</a> depending
+on the value of the <code><i>use-apache-log-p</i></code> argument
+to <a href="#start-server"><code>START-SERVER</code></a>. <code><i>log-level</i></code>
+should be one of the
+keywords <code>:EMERG</code>, <code>:ALERT</code>, <code>:CRIT</code>, <code>:ERROR</code>, <code>:WARNING</code>, <code>:NOTICE</code>, <code>:INFO</code>,
+or <code>:DEBUG</code> which correspond to the various Apache log
+levels. <code><i>log-level</i></code> can also be <code>NIL</code> (in
+which case mod_lisp's default log level is used. If Apache isn't used, the log level is just written
+to the log file unless it's <code>NIL</code>.
+<code><i>format</i></code> and <code><i>args</i></code> are used as with
+<a href='http://www.lispworks.com/documentation/HyperSpec/Body/f_format.htm'><code>FORMAT</code></a>.
+<p>
+<code>LOG-MESSAGE</code> is a generic function, so you can specialize it or bypass it completely with an around method.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="log-message*"><b>log-message*</b> <i>format</i> <tt>&rest</tt> <i>args</i> => |</a>
+
+<blockquote><br>
+Like <a href="#log-message"><code>LOG-MESSAGE</code></a> but with <code><i>log-level</i></code> set to <a href="#*default-log-level*"><code>*DEFAULT-LOG-LEVEL*</code></a>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*default-log-level*"><b>*default-log-level*</b></a>
+
+<blockquote><br>
+The log level used by <a href="#log-message*"><code>LOG-MESSAGE*</code></a>. The initial value is <code>NIL</code>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*log-lisp-errors-p*"><b>*log-lisp-errors-p*</b></a>
+
+<blockquote><br>
+Whether unhandled errors in <a href='#handlers'>handlers</a> should be logged. See also <a href="#*lisp-errors-log-level*"><code>*LISP-ERRORS-LOG-LEVEL*</code></a>. The default value is <code>T</code>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*lisp-errors-log-level*"><b>*lisp-errors-log-level*</b></a>
+
+<blockquote><br>
+The log level used to log Lisp errors. See also <a href="#*log-lisp-errors-p*"><code>*LOG-LISP-ERRORS-P*</code></a>. The default value is <code>:ERROR</code>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*log-lisp-warnings-p*"><b>*log-lisp-warnings-p*</b></a>
+
+<blockquote><br>
+Whether unhandled warnings in <a href='#handlers'>handlers</a> should be logged. See also <a href="#*lisp-warnings-log-level*"><code>*LISP-WARNINGS-LOG-LEVEL*</code></a>. The default value is <code>T</code>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*lisp-warnings-log-level*"><b>*lisp-warnings-log-level*</b></a>
+
+<blockquote><br>
+The log level used to log Lisp warnings. See also <a href="#*log-lisp-warnings-p*"><code>*LOG-LISP-WARNINGS-P*</code></a>. The default value is <code>:WARNING</code>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*log-lisp-backtraces-p*"><b>*log-lisp-backtraces-p*</b></a>
+
+<blockquote><br>
+Whether backtraces should also be logged in addition to error messages and warnings. This value will only have effect if <a href="#*log-lisp-errors-p*"><code>*LOG-LISP-ERRORS-P*</code></a> or <a href="#*log-lisp-warnings-p*"><code>*LOG-LISP-WARNINGS-P*</code></a> is <em>true</em>. The default value is <code>NIL</code>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*log-prefix*"><b>*log-prefix*</b></a>
+
+<blockquote><br>
+All messages written to the Apache error log by Hunchentoot are prepended by a string which is the value of this variable enclosed in square brackets. If the value is <code>NIL</code>, however, no such prefix will be written. If the value is <code>T</code> (which is the default), the prefix will be <code>"[Hunchentoot]"</code>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*show-lisp-errors-p*"><b>*show-lisp-errors-p*</b></a>
+
+<blockquote><br>
+Whether unhandled Lisp errors should be shown to the user. If this value is <code>NIL</code> (which is the default), only the message <em>An error has occurred</em> will be shown.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*show-lisp-backtraces-p*"><b>*show-lisp-backtraces-p*</b></a>
+
+<blockquote><br>
+Whether backtraces should also be shown to the user. This value will only have effect if <a href="#*show-lisp-errors-p*"><code>*SHOW-LISP-ERRORS-P*</code></a> is <em>true</em>. The default value is <code>NIL</code>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*show-access-log-messages*"><b>*show-access-log-messages*</b></a>
+
+<blockquote><br>
+If this variable is <em>true</em> <em>and</em> if the value of the <code><i>use-apache-log-p</i></code> argument to <a href="#start-server"><code>START-SERVER</code></a> was <code>NIL</code>, then for each request a line somewhat similar to what can be found in Apache's access log will be written to the <a href="#log-file">log file</a>. The default value of this variable is <code>T</code>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none
+name="*http-error-handler*"><b>*http-error-handler*</b></a>
+
+<blockquote><br>
+This variable holds <code>NIL</code> (the default) or a <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function…">function designator</a> for a function of one argument. The function gets called if the responsible <a href="#handlers">handler</a> has set a return code which is not in <a href="#*approved-return-codes*"><code>*APPROVED-RETURN-CODES*</code></a> and <a href="#*handle-http-errors-p*"><code>*HANDLE-HTTP-ERRORS-P*</code></a> is true. It receives the return code as its argument and can return the contents of an error page or <code>NIL</code> if it refuses to handle the error, i.e. if Hunchentoot's default error page should be shown. (Note that the function can access the request and reply data.)
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none
+name="*handle-http-errors-p*"><b>*handle-http-errors-p*</b></a>
+
+<blockquote><br> This variable holds a generalized boolean that
+determines whether return codes not in <a href="#*approved-return-codes*"><code>*APPROVED-RETURN-CODES*</code></a>
+are treated specially. When its value is true (the default), either a
+default body for the return code or the result of
+calling <a
+href="#*http-error-handler*"><code>*HTTP-ERROR-HANDLER*</code></a> is
+used. When the value is <code>NIL</code>, no special action is taken
+and you are expected to supply your own response body to describe the
+error.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none
+name="*approved-return-codes*"><b>*approved-return-codes*</b></a>
+<blockquote><br>
+A list of return codes the server should not treat as an error -
+see <a href="#*handle-http-errors-p*"><code>*HANDLE-HTTP-ERRORS-P*</code></a>. The initial value is the list with the values of
+<a href="#+http-ok+"><code>+HTTP-OK+</code></a>, <a href="#+http-no-content+"><code>+HTTP-NO-CONTENT+</code></a>, <a href="#+http-multi-status+"><code>+HTTP-MULTI-STATUS+</code></a>, and <a href="#+http-not-modified+"><code>+HTTP-NOT-MODIFIED+</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="get-backtrace"><b>get-backtrace</b> <i>condition</i> => <i>backtrace</i></a>
+
+<blockquote><br>
+This is the function that is used internally by Hunchentoot to
+show or log backtraces. It accepts a condition object <code><i>condition</i></code> and
+returns a string with the corresponding backtrace.
+</blockquote>
+
+<h4><a class=none name="debug">Debugging Hunchentoot applications</a></h4>
+
+The best option to debug a Hunchentoot application is
+probably <a href="#*catch-errors-p*">to use the debugger</a>.
+<p>
+One important thing you should try if you're behind mod_lisp is to
+use <a href="#log">an external log file</a> (as opposed to Apache's
+log) because it can reveal error messages that might otherwise get
+lost if something's broken in the communication between Hunchentoot
+and mod_lisp.
+<p>
+Good luck... :)
+
+<p><br>[Special variable]
+<br><a class=none name="*catch-errors-p*"><b>*catch-errors-p*</b></a>
+
+<blockquote><br> If the value of this variable is <code>NIL</code>
+(the default is <code>T</code>), then errors which happen while a
+request is handled aren't <a href="#log">caught as usual</a>, but
+instead your
+Lisp's <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_d.htm#debugger">debugger</a>
+is <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_invoke.htm">invoked</a>.
+This variable should obviously always be set to a <em>true</em> value
+in a production environment.
+See <a
+href="#maybe-invoke-debugger"><code>MAYBE-INVOKE-DEBUGGER</code></a>
+if you want to fine-tune this behaviour.
+</blockquote>
+
+<p><br>[Generic function]
+<br><a class=none name="maybe-invoke-debugger"><b>maybe-invoke-debugger</b> <i>condition</i> => |</a>
+
+<blockquote><br>
+This generic function is called whenever a
+<a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/09_.htm">condition</a> <code><i>condition</i></code>
+is signaled in Hunchentoot. You might want to specialize it on
+specific condition classes for debugging purposes. The default
+method <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_invoke.htm">invokes
+the debugger</a> with <code><i>condition</i></code> if
+<a href="#*catch-errors-p*"><code>*CATCH-ERRORS-P*</code></a> is <code>NIL</code>.
+</blockquote>
+
+
+<p><br>[Special variable]
+<br><a class=none name="*header-stream*"><b>*header-stream*</b></a>
+
+<blockquote><br>
+If this variable is not <code>NIL</code>, it should be bound to a stream to
+which incoming and outgoing headers will be written for debugging
+purposes.
+</blockquote>
+
+<h4><a class=none name="misc">Miscellaneous</a></h4>
+
+Various functions and variables which didn't fit into one of the other categories.
+
+<p><br>[Function]
+<br><a class=none name="ssl-p"><b>ssl-p</b> => generalized-boolean</a>
+
+<blockquote><br>
+Whether the current connection to the client is secure.
+</blockquote>
+
+<p><br>[Symbol]
+<br><a class=none name="handler-done"><b>handler-done</b></a>
+
+<blockquote><br> This is a <a
+href='http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#catch_tag'><em>catch
+tag</em></a> which names a <a
+href='http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#catch'><em>catch</em></a>
+which is active during the lifetime of a <a
+href='#handlers'>handler</a>. The handler can at any time <a
+href='http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_t.htm#throw'><em>throw</em></a>
+the outgoing content body (or <code>NIL</code>) to this catch to immediately abort handling the request. See the source code of <a href="#redirect"><code>REDIRECT</code></a> for an example.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="no-cache"><b>no-cache</b> => |</a>
+
+<blockquote><br>
+This function will set appropriate outgoing headers to completely prevent caching on virtually all browsers.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="handle-if-modified-since"><b>handle-if-modified-since</b> <i>time</i> => |</a>
+
+<blockquote><br>
+
+This function is designed to be used inside a <a
+href='#handlers'>handler</a>. If the client has sent an
+'If-Modified-Since' header (see <a
+href='http://www.faqs.org/rfcs/rfc2616.html'>RFC 2616</a>,
+section 14.25) and the time specified matches the universal time
+<code><i>time</i></code> then the header <a
+href="#+http-not-modified+"><code>+HTTP-NOT-MODIFIED+</code></a> with
+no content is immediately returned to the client.
+<p>
+Note that for this function to be useful you should usually send
+'Last-Modified' headers back to the client. See the code of <a
+href="#create-static-file-dispatcher-and-handler"><code>CREATE-STATIC-FILE-DISPATCHER-AND-HANDLER</code></a>
+for an example.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="rfc-1123-date"><b>rfc-1123-date</b> <tt>&optional</tt> <i>time</i> => <i>string</i></a>
+
+<blockquote><br>
+
+This function accepts a universal time <code><i>time</i></code>
+(default is the current time) and returns a string which encodes this time according to <a
+href='http://www.faqs.org/rfcs/rfc1123.html'>RFC 1123</a>. This can be used to send a 'Last-Modified' header - see <a
+href="#handle-if-modified-since"><code>HANDLE-IF-MODIFIED-SINCE</code></a>.
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="redirect"><b>redirect</b> <i>target</i> <tt>&key</tt> <i>host port protocol add-session-id permanently</i> => |</a>
+
+<blockquote><br> Sends back appropriate headers to redirect the client
+to <code><i>target</i></code> (a string).
+
+If <code><i>target</i></code> is a full URL starting with a scheme, <code><i>host</i></code>, <code><i>port</i></code>, and <code><i>protocol</i></code>
+are ignored. Otherwise, <code><i>target</i></code> should denote the path part of a
+URL, <code><i>protocol</i></code> must be one of the keywords <code>:HTTP</code> or <code>:HTTPS</code>, and
+the URL to redirect to will be constructed from <code><i>host</i></code>, <code><i>port</i></code>, <code><i>protocol</i></code>,
+and <code><i>target</i></code>.
+<p>
+If <code><i>permanently</i></code>
+is <em>true</em> (the default is <code>NIL</code>), a 301 status
+code will be sent, otherwise a 302 status code. If <code><i>host</i></code>
+is not provided, the current host (see <a
+href="#host"><code>HOST</code></a>) will be
+used. If <code><i>protocol</i></code> is the
+keyword <code>:HTTPS</code>, the client will be redirected to a https
+URL, if it's <code>:HTTP</code> it'll be sent to a http URL. If
+both <code><i>host</i></code> and <code><i>protocol</i></code> aren't
+provided, then the value of <code><i>protocol</i></code> will
+match the current request.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="require-authorization"><b>require-authorization</b> <tt>&optional</tt> <i>realm</i> => |</a>
+
+<blockquote><br>
+Sends back appropriate headers to require basic HTTP authentication (see <a href='http://www.faqs.org/rfcs/rfc2617.html'>RFC 2617</a>) for the realm <code><i>realm</i></code>. The default value for <code><i>realm</i></code> is <code>"Hunchentoot"</code>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="escape-for-html"><b>escape-for-html</b> <i>string</i> => <i>escaped-string</i></a>
+
+<blockquote><br>
+Escapes all occurrences of the characters <code>#\<</code>, <code>#\></code>, <code>#\'</code>, <code>#"</code>, and <code>#\&</code> within <code><i>string</i></code> for HTML output.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="url-encode"><b>url-encode</b> <i>string</i> <tt>&optional</tt> <i>external-format</i> => <i>url-encoded-string</i></a>
+
+<blockquote><br>
+URL-encodes a string using the external format <code><i>external-format</i></code>. The default for <code><i>external-format</i></code> is the value of <a href="#*hunchentoot-default-external-format*"><code>*HUNCHENTOOT-DEFAULT-EXTERNAL-FORMAT*</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="url-decode"><b>url-decode</b> <i>string</i> <tt>&optional</tt> <i>external-format</i> => <i>url-encoded-string</i></a>
+
+<blockquote><br>
+URL-decodes a string using the external format <code><i>external-format</i></code>, i.e. this is the inverse of <a href="#url-encode"><code>URL-ENCODE</code></a>.
+It is assumed that you'll rarely need this function, if ever. But just in case - here it is.
+The default for <code><i>external-format</i></code> is the value of <a href="#*hunchentoot-default-external-format*"><code>*HUNCHENTOOT-DEFAULT-EXTERNAL-FORMAT*</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="http-token-p"><b>http-token-p</b> <i>object</i> => <i>generalized-boolean</i></a>
+
+<blockquote><br> This function tests
+whether <code><i>object</i></code> is a non-empty string which is
+a <em>token</em> according to <a href='http://www.faqs.org/rfcs/rfc2068.html'>RFC 2068</a> (i.e. whether it may be used
+for, say, cookie names).
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*tmp-directory*"><b>*tmp-directory*</b></a>
+
+<blockquote><br>
+This should be a pathname denoting a directory where temporary files can be stored. It is used for <a href="#upload">file uploads</a>.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none
+name="*hunchentoot-default-external-format*"><b>*hunchentoot-default-external-format*</b></a>
+
+<blockquote><br> The (<a href="http://weitz.de/flexi-streams/">flexi
+stream</a>) external format used when computing
+the <a href="#requests"><code>REQUEST</code></a> object. The default
+value is the result of evaluating
+<pre>
+(<a class=noborder href="http://weitz.de/flexi-streams/#make-external-format">flex:make-external-format</a> :latin1 :eol-style :lf)
+</pre>
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="mime-type"><b>mime-type</b> <i>pathspec</i> => <i>string</i></a>
+
+<blockquote><br>
+Given a pathname designator <code><i>pathspec</i></code> returns the <a href="http://en.wikipedia.org/wiki/Internet_media_type">MIME type</a>
+(as a string) corresponding to the suffix of the file denoted by
+<code><i>pathspec</i></code> (or <code>NIL</code> if none can be
+found). This is based on the table coming with the Apache
+distribution with some additions.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="reason-phrase"><b>reason-phrase</b> <i>return-code</i> => <i>string</i></a>
+
+<blockquote><br> Returns a reason phrase for the HTTP return
+code <code><i>return-code</i></code> (which should be an integer)
+or <code>NIL</code> for return codes Hunchentoot doesn't know.
+</blockquote>
+
+<br> <br><h3><a class=none name="ht-mp">The HUNCHENTOOT-MP package</a></h3>
+
+Hunchentoot creates an
+additional <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/11_.htm">package</a> <code>HUNCHENTOOT-MP</code>
+which exports a couple of MP-related symbols
+(namely <code>*CURRENT-PROCESS*</code>, <code>MAKE-LOCK</code>, <code>WITH-LOCK</code>, <code>PROCESS-RUN-FUNCTION</code>,
+and <code>PROCESS-KILL</code>). These functions and macros have to be
+in Hunchentoot's small portability shim anyway and even if you don't
+spawn your own threads there might be occasions where you want to at
+least use the lock-related functionality to write thread-safe portable
+code. See the corresponding documentation strings and/or the source
+code for more information.
+
+<br> <br><h3><a class=none name="performance">Performance</a></h3>
+
+If you're concerned about Hunchentoot's performance, you should first
+and foremost check if you aren't wasting your time with premature
+optimization. Make a reasonable estimate of the amount of traffic
+your website should be able to handle and don't try to benchmark for
+loads Google would be proud of. Here's a part of an interview with
+someone called John Witchel about his experiences with his
+company <em>Red Gorilla</em> that can't be quoted often enough (it
+seems the original source of the interview has vanished):
+
+<blockquote>
+<b>Q:</b> If you could go back and change anything, would <em>Red Gorilla</em> still be
+in business today?
+<p>
+<b>A:</b> Yes. I would start small and grow as the demand grew. That's what I'm
+doing now.
+<p>
+Back then we planned to be huge from the outset. So we built this
+monster platform on BEA, Sun and Oracle. We had huge dedicated
+connectivity pipes. We had two full racks clustered and fully
+redundant. We had E450's with RAID-5 and all 4 CPU slots filled,
+E250s, F5 load balancers... the cost of keeping that system on was
+enormous. The headcount to keep it humming was enormous too.
+<p>
+The truth is, we could have run the whole company on my laptop using a
+cable modem connection.
+</blockquote>
+
+Having said that, my experience is that Hunchentoot doesn't have to
+hide when it comes to
+serving <a href="#handle-static-file">static files</a>. If
+you <em>really</em> have performance problems with Hunchentoot, there
+are two things I'm aware of you should watch out for.
+<ul>
+<li>Check how your Lisp implementation implements multi-processing.
+While I write this (April 2007), some Lisps, like CMUCL, still use
+their
+own <a
+href="http://en.wikipedia.org/wiki/Multithreading"><em>green</em>
+threads</a>, and some others, like AllegroCL and LispWorks, use
+OS-threads but allow only one Lisp thread at a time. Unless you're
+using a Lisp that employs "real" symmetric multi-processing like SBCL
+(on some platforms) or OpenMCL, you shouldn't compare apples with
+oranges. (Note: For CMUCL, you also shouldn't forget to use the
+dreaded <a
+href="http://wiki.alu.org/Lisp_Gotchas"><code>MP::STARTUP-IDLE-AND-TOP-LEVEL-LOOPS</code></a>.)
+<li>All text output sent from <a href="#handlers">handlers</a> goes
+through two layers
+of <a
+href="http://www.nhplace.com/kent/CL/Issues/stream-definition-by-user.html">Gray
+streams</a> by default
+(<a href="http://weitz.de/flexi-streams/">FLEXI-STREAMS</a>
+and <a href="http://weitz.de/chunga/">Chunga</a>). This isn't an
+issue for small to medium-sized pages, but can be for large ones.
+There are several ways to cope with this
+- <a
+href="http://common-lisp.net/pipermail/tbnl-devel/2007-March/001093.html">return
+binary data from
+handlers</a>, <a
+href="http://common-lisp.net/pipermail/tbnl-devel/2007-March/001099.html">bypass
+FLEXI-STREAMS</a>, sit behind <a href="#mod_lisp">mod_lisp</a>, etc.
+Try it, and if you <em>really</em> think that Hunchentoot is too slow
+for what you're trying to do and what you'll need, ask on
+the <a href="#href">mailing list</a> and we'll try to help.
+</ul>
+
+<br> <br><h3><a class=none name="history">History</a></h3>
+
+Hunchentoot's predecessor <a href="http://weitz.de/tbnl/">TBNL</a>
+(which is short for "To Be Named Later") grew over the years
+as a toolkit that I used for various commercial and private
+projects. In August 2003, Daniel Barlow started
+a <a href='http://article.gmane.org/gmane.lisp.web/148'>review of web
+APIs</a> on the <a href='http://www.red-bean.com/lispweb/'>lispweb</a>
+mailing list and
+I <a href='http://article.gmane.org/gmane.lisp.web/153'>described</a>
+the API of my hitherto-unreleased bunch of code (and christened it
+"TBNL").
+<p>
+It turned out that <a href='http://www.jeffcaldwell.com/'>Jeff
+Caldwell</a> had worked on something similar so he emailed me and
+proposed to join our efforts. As I had no immediate plans to release
+my code (which was poorly organized, undocumented, and mostly
+CMUCL-specific), I gave it to Jeff and he worked towards a release. He
+added docstrings, refactored, added some stuff, and based it on KMRCL
+to make it portable across several Lisp implementations.
+<p>
+Unfortunately, Jeff is at least as busy as I am so he didn't find the
+time to finish a full release. But in spring 2004 I needed a
+documented version of the code for a client of mine who thought
+it would be good if the toolkit were publicly available under an open
+source license. So I took Jeff's code, refactored again (to sync with
+the changes I had done in the meantime), and added documentation.
+This resulted in TBNL 0.1.0 (which initially required mod_lisp as its
+front-end). Jeff's code (which includes a lot more stuff that I
+didn't use) is still available from his own
+website <a href='http://tbnl.org/'>tbnl.org</a>.
+<p>
+In March 2005, Bob Hutchinson sent patches which enabled TBNL to use
+other front-ends than mod_lisp. This made me aware that TBNL was
+already <em>almost</em> a full web server, so eventually I wrote
+Hunchentoot which <em>was</em> a full web server, implemented as a
+wrapper around TBNL. Hunchentoot 0.1.0 was released at the end of
+2005 and was originally LispWorks-only.
+<p>
+Hunchentoot 0.4.0, released in October 2006, was the first release
+which also worked with other Common Lisp implementations. It is a
+major rewrite and also incorporates most of TBNL and replaces
+it completely.
+
+<br> <br><h3><a class=none name="index">Symbol index</a></h3>
+
+Here are all exported symbols of the <code>HUNCHENTOOT</code> package
+in alphabetical order linked to their corresponding entries:
+
+ <ul>
+ <li><a href="#*approved-return-codes*"><code>*approved-return-codes*</code></a>
+ <li><a href="#*catch-errors-p*"><code>*catch-errors-p*</code></a>
+ <li><a href="#*cleanup-function*"><code>*cleanup-function*</code></a>
+ <li><a href="#*cleanup-interval*"><code>*cleanup-interval*</code></a>
+ <li><a href="#*content-types-for-url-rewrite*"><code>*content-types-for-url-rewrite*</code></a>
+ <li><a href="#*default-content-type*"><code>*default-content-type*</code></a>
+ <li><a href="#*default-handler*"><code>*default-handler*</code></a>
+ <li><a href="#*default-log-level*"><code>*default-log-level*</code></a>
+ <li><a href="#*default-read-timeout*"><code>*default-read-timeout*</code></a>
+ <li><a href="#*default-write-timeout*"><code>*default-write-timeout*</code></a>
+ <li><a href="#*dispatch-table*"><code>*dispatch-table*</code></a>
+ <li><a href="#*file-upload-hook*"><code>*file-upload-hook*</code></a>
+ <li><a href="#*handle-http-errors-p*"><code>*handle-http-errors-p*</code></a>
+ <li><a href="#*header-stream*"><code>*header-stream*</code></a>
+ <li><a href="#*http-error-handler*"><code>*http-error-handler*</code></a>
+ <li><a href="#*hunchentoot-default-external-format*"><code>*hunchentoot-default-external-format*</code></a>
+ <li><a href="#*lisp-errors-log-level*"><code>*lisp-errors-log-level*</code></a>
+ <li><a href="#*lisp-warnings-log-level*"><code>*lisp-warnings-log-level*</code></a>
+ <li><a href="#*log-lisp-backtraces-p*"><code>*log-lisp-backtraces-p*</code></a>
+ <li><a href="#*log-lisp-errors-p*"><code>*log-lisp-errors-p*</code></a>
+ <li><a href="#*log-lisp-warnings-p*"><code>*log-lisp-warnings-p*</code></a>
+ <li><a href="#*log-prefix*"><code>*log-prefix*</code></a>
+ <li><a href="#*meta-dispatcher*"><code>*meta-dispatcher*</code></a>
+ <li><a href="#*methods-for-post-parameters*"><code>*methods-for-post-parameters*</code></a>
+ <li><a href="#*reply*"><code>*reply*</code></a>
+ <li><a href="#*request*"><code>*request*</code></a>
+ <li><a href="#*rewrite-for-session-urls*"><code>*rewrite-for-session-urls*</code></a>
+ <li><a href="#*server*"><code>*server*</code></a>
+ <li><a href="#*session*"><code>*session*</code></a>
+ <li><a href="#*session-cookie-name*"><code>*session-cookie-name*</code></a>
+ <li><a href="#*session-gc-frequency*"><code>*session-gc-frequency*</code></a>
+ <li><a href="#*session-max-time*"><code>*session-max-time*</code></a>
+ <li><a href="#*session-removal-hook*"><code>*session-removal-hook*</code></a>
+ <li><a href="#*show-access-log-messages*"><code>*show-access-log-messages*</code></a>
+ <li><a href="#*show-lisp-backtraces-p*"><code>*show-lisp-backtraces-p*</code></a>
+ <li><a href="#*show-lisp-errors-p*"><code>*show-lisp-errors-p*</code></a>
+ <li><a href="#*tmp-directory*"><code>*tmp-directory*</code></a>
+ <li><a href="#*use-remote-addr-for-sessions*"><code>*use-remote-addr-for-sessions*</code></a>
+ <li><a href="#*use-user-agent-for-sessions*"><code>*use-user-agent-for-sessions*</code></a>
+ <li><a href="#+http-accepted+"><code>+http-accepted+</code></a>
+ <li><a href="#+http-authorization-required+"><code>+http-authorization-required+</code></a>
+ <li><a href="#+http-bad-gateway+"><code>+http-bad-gateway+</code></a>
+ <li><a href="#+http-bad-request+"><code>+http-bad-request+</code></a>
+ <li><a href="#+http-conflict+"><code>+http-conflict+</code></a>
+ <li><a href="#+http-continue+"><code>+http-continue+</code></a>
+ <li><a href="#+http-created+"><code>+http-created+</code></a>
+ <li><a href="#+http-expectation-failed+"><code>+http-expectation-failed+</code></a>
+ <li><a href="#+http-failed-dependency+"><code>+http-failed-dependency+</code></a>
+ <li><a href="#+http-forbidden+"><code>+http-forbidden+</code></a>
+ <li><a href="#+http-gateway-time-out+"><code>+http-gateway-time-out+</code></a>
+ <li><a href="#+http-gone+"><code>+http-gone+</code></a>
+ <li><a href="#+http-internal-server-error+"><code>+http-internal-server-error+</code></a>
+ <li><a href="#+http-length-required+"><code>+http-length-required+</code></a>
+ <li><a href="#+http-method-not-allowed+"><code>+http-method-not-allowed+</code></a>
+ <li><a href="#+http-moved-permanently+"><code>+http-moved-permanently+</code></a>
+ <li><a href="#+http-moved-temporarily+"><code>+http-moved-temporarily+</code></a>
+ <li><a href="#+http-multi-status+"><code>+http-multi-status+</code></a>
+ <li><a href="#+http-multiple-choices+"><code>+http-multiple-choices+</code></a>
+ <li><a href="#+http-no-content+"><code>+http-no-content+</code></a>
+ <li><a href="#+http-non-authoritative-information+"><code>+http-non-authoritative-information+</code></a>
+ <li><a href="#+http-not-acceptable+"><code>+http-not-acceptable+</code></a>
+ <li><a href="#+http-not-found+"><code>+http-not-found+</code></a>
+ <li><a href="#+http-not-implemented+"><code>+http-not-implemented+</code></a>
+ <li><a href="#+http-not-modified+"><code>+http-not-modified+</code></a>
+ <li><a href="#+http-ok+"><code>+http-ok+</code></a>
+ <li><a href="#+http-partial-content+"><code>+http-partial-content+</code></a>
+ <li><a href="#+http-payment-required+"><code>+http-payment-required+</code></a>
+ <li><a href="#+http-precondition-failed+"><code>+http-precondition-failed+</code></a>
+ <li><a href="#+http-proxy-authentication-required+"><code>+http-proxy-authentication-required+</code></a>
+ <li><a href="#+http-request-entity-too-large+"><code>+http-request-entity-too-large+</code></a>
+ <li><a href="#+http-request-time-out+"><code>+http-request-time-out+</code></a>
+ <li><a href="#+http-request-uri-too-large+"><code>+http-request-uri-too-large+</code></a>
+ <li><a href="#+http-requested-range-not-satisfiable+"><code>+http-requested-range-not-satisfiable+</code></a>
+ <li><a href="#+http-reset-content+"><code>+http-reset-content+</code></a>
+ <li><a href="#+http-see-other+"><code>+http-see-other+</code></a>
+ <li><a href="#+http-service-unavailable+"><code>+http-service-unavailable+</code></a>
+ <li><a href="#+http-switching-protocols+"><code>+http-switching-protocols+</code></a>
+ <li><a href="#+http-temporary-redirect+"><code>+http-temporary-redirect+</code></a>
+ <li><a href="#+http-unsupported-media-type+"><code>+http-unsupported-media-type+</code></a>
+ <li><a href="#+http-use-proxy+"><code>+http-use-proxy+</code></a>
+ <li><a href="#+http-version-not-supported+"><code>+http-version-not-supported+</code></a>
+ <li><a href="#authorization"><code>authorization</code></a>
+ <li><a href="#aux-request-value"><code>aux-request-value</code></a>
+ <li><a href="#content-length"><code>content-length</code></a>
+ <li><a href="#content-type"><code>content-type</code></a>
+ <li><a href="#cookie-domain"><code>cookie-domain</code></a>
+ <li><a href="#cookie-expires"><code>cookie-expires</code></a>
+ <li><a href="#cookie-http-only"><code>cookie-http-only</code></a>
+ <li><a href="#cookie-in"><code>cookie-in</code></a>
+ <li><a href="#cookie-name"><code>cookie-name</code></a>
+ <li><a href="#cookie-out"><code>cookie-out</code></a>
+ <li><a href="#cookie-path"><code>cookie-path</code></a>
+ <li><a href="#cookie-secure"><code>cookie-secure</code></a>
+ <li><a href="#cookie-value"><code>cookie-value</code></a>
+ <li><a href="#cookies-in"><code>cookies-in</code></a>
+ <li><a href="#cookies-out"><code>cookies-out</code></a>
+ <li><a href="#create-folder-dispatcher-and-handler"><code>create-folder-dispatcher-and-handler</code></a>
+ <li><a href="#create-prefix-dispatcher"><code>create-prefix-dispatcher</code></a>
+ <li><a href="#create-regex-dispatcher"><code>create-regex-dispatcher</code></a>
+ <li><a href="#create-static-file-dispatcher-and-handler"><code>create-static-file-dispatcher-and-handler</code></a>
+ <li><a href="#default-dispatcher"><code>default-dispatcher</code></a>
+ <li><a href="#define-easy-handler"><code>define-easy-handler</code></a>
+ <li><a href="#delete-aux-request-value"><code>delete-aux-request-value</code></a>
+ <li><a href="#delete-session-value"><code>delete-session-value</code></a>
+ <li><a href="#dispatch-easy-handlers"><code>dispatch-easy-handlers</code></a>
+ <li><a href="#dispatch-request"><code>dispatch-request</code></a>
+ <li><a href="#do-sessions"><code>do-sessions</code></a>
+ <li><a href="#escape-for-html"><code>escape-for-html</code></a>
+ <li><a href="#get-backtrace"><code>get-backtrace</code></a>
+ <li><a href="#get-parameter"><code>get-parameter</code></a>
+ <li><a href="#get-parameters"><code>get-parameters</code></a>
+ <li><a href="#handle-if-modified-since"><code>handle-if-modified-since</code></a>
+ <li><a href="#handle-static-file"><code>handle-static-file</code></a>
+ <li><a href="#handler-done"><code>handler-done</code></a>
+ <li><a href="#header-in"><code>header-in</code></a>
+ <li><a href="#header-out"><code>header-out</code></a>
+ <li><a href="#headers-in"><code>headers-in</code></a>
+ <li><a href="#headers-out"><code>headers-out</code></a>
+ <li><a href="#host"><code>host</code></a>
+ <li><a href="#http-token-p"><code>http-token-p</code></a>
+ <li><a href="#log-file"><code>log-file</code></a>
+ <li><a href="#log-message"><code>log-message</code></a>
+ <li><a href="#log-message*"><code>log-message*</code></a>
+ <li><a href="#maybe-invoke-debugger"><code>maybe-invoke-debugger</code></a>
+ <li><a href="#mime-type"><code>mime-type</code></a>
+ <li><a href="#mod-lisp-id"><code>mod-lisp-id</code></a>
+ <li><a href="#no-cache"><code>no-cache</code></a>
+ <li><a href="#parameter"><code>parameter</code></a>
+ <li><a href="#post-parameter"><code>post-parameter</code></a>
+ <li><a href="#post-parameters"><code>post-parameters</code></a>
+ <li><a href="#query-string"><code>query-string</code></a>
+ <li><a href="#raw-post-data"><code>raw-post-data</code></a>
+ <li><a href="#real-remote-addr"><code>real-remote-addr</code></a>
+ <li><a href="#reason-phrase"><code>reason-phrase</code></a>
+ <li><a href="#recompute-request-parameters"><code>recompute-request-parameters</code></a>
+ <li><a href="#redirect"><code>redirect</code></a>
+ <li><a href="#referer"><code>referer</code></a>
+ <li><a href="#remote-addr"><code>remote-addr</code></a>
+ <li><a href="#remote-port"><code>remote-port</code></a>
+ <li><a href="#remote-session"><code>remote-session</code></a>
+ <li><a href="#reply-external-format"><code>reply-external-format</code></a>
+ <li><a href="#request-method"><code>request-method</code></a>
+ <li><a href="#request-uri"><code>request-uri</code></a>
+ <li><a href="#require-authorization"><code>require-authorization</code></a>
+ <li><a href="#reset-sessions"><code>reset-sessions</code></a>
+ <li><a href="#return-code"><code>return-code</code></a>
+ <li><a href="#rfc-1123-date"><code>rfc-1123-date</code></a>
+ <li><a href="#script-name"><code>script-name</code></a>
+ <li><a href="#send-headers"><code>send-headers</code></a>
+ <li><a href="#server-addr"><code>server-addr</code></a>
+ <li><a href="#server-address"><code>server-address</code></a>
+ <li><a href="#server-dispatch-table"><code>server-dispatch-table</code></a>
+ <li><a href="#server-local-port"><code>server-local-port</code></a>
+ <li><a href="#server-name"><code>server-name</code></a>
+ <li><a href="#server-port"><code>server-port</code></a>
+ <li><a href="#server-protocol"><code>server-protocol</code></a>
+ <li><a href="#session-cookie-value"><code>session-cookie-value</code></a>
+ <li><a href="#session-counter"><code>session-counter</code></a>
+ <li><a href="#session-gc"><code>session-gc</code></a>
+ <li><a href="#session-max-time"><code>session-max-time</code></a>
+ <li><a href="#session-too-old-p"><code>session-too-old-p</code></a>
+ <li><a href="#session-remote-addr"><code>session-remote-addr</code></a>
+ <li><a href="#session-user-agent"><code>session-user-agent</code></a>
+ <li><a href="#session-value"><code>session-value</code></a>
+ <li><a href="#set-cookie"><code>set-cookie</code></a>
+ <li><a href="#set-cookie*"><code>set-cookie*</code></a>
+ <li><a href="#ssl-p"><code>ssl-p</code></a>
+ <li><a href="#ssl-session-id"><code>ssl-session-id</code></a>
+ <li><a href="#start-server"><code>start-server</code></a>
+ <li><a href="#start-session"><code>start-session</code></a>
+ <li><a href="#stop-server"><code>stop-server</code></a>
+ <li><a href="#url-decode"><code>url-decode</code></a>
+ <li><a href="#url-encode"><code>url-encode</code></a>
+ <li><a href="#user-agent"><code>user-agent</code></a>
+ </ul>
+
+<br> <br><h3><a class=none name="ack">Acknowledgements</a></h3>
+
+Thanks to Jeff Caldwell - TBNL would not have been released without
+his efforts. Thanks to <a href="http://www.fractalconcept.com/">Marc
+Battyani</a> for mod_lisp and
+to <a href="http://www.swiss.ai.mit.edu/~cph/">Chris Hanson</a> for
+mod_lisp2. Thanks
+to <a href="http://www.cliki.net/Stefan%20Scholl">Stefan Scholl</a>
+and Travis Cross for various additions and fixes to TBNL,
+to <a href="http://www.foldr.org/~michaelw/">Michael Weber</a> for
+initial file upload code, and
+to <a href="http://www.ltn.lv/~jonis/">Janis Dzerins</a> for
+his <a href="http://common-lisp.net/project/rfc2388/">RFC 2388
+code</a>. Thanks to Bob Hutchison for his code for multiple front-ends
+(which made me realize that TBNL was already pretty close to a "real"
+web server) and the initial UTF-8 example. Thanks to John
+Foderaro's <a
+href="http://opensource.franz.com/aserve/index.html">AllegroServe</a>
+for inspiration. Thanks
+to <a href="http://www.htg1.de/">Uwe von Loh</a> for the <a href="http://www.htg1.de/hunchentoot/hunchentoot.html">Hunchentoot
+logo</a>.
+<p>
+Hunchentoot originally used code
+from <a href="http://www.cliki.net/ACL-COMPAT">ACL-COMPAT</a>,
+specifically the chunking code from Jochen Schmidt. (This has been
+replaced by <a href="http://weitz.de/chunga/">Chunga</a>.) When I
+ported Hunchentoot to other Lisps than LispWorks, I stole code from
+ACL-COMPAT, <a href="http://www.cliki.net/kmrcl">KMRCL</a>,
+and <a href="http://www.cliki.net/trivial-sockets">trivial-sockets</a>
+for implementation-dependent stuff like sockets and MP.
+<p>
+Parts of this documentation were prepared
+with <a
+href="http://weitz.de/documentation-template/">DOCUMENTATION-TEMPLATE</a>, no animals were harmed.
+</p>
+<p>
+$Header: /usr/local/cvsrep/hunchentoot/doc/index.html,v 1.122 2007/11/15 07:29:58 edi Exp $
+<p><a href="http://weitz.de/index.html">BACK TO MY HOMEPAGE</a>
+
+</body>
+</html>
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/doc/index.html
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/easy-handlers.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/easy-handlers.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/easy-handlers.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,319 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/easy-handlers.lisp,v 1.12 2007/05/25 11:32:50 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(defun compute-real-name (symbol)
+ "Computes the `real' paramater name \(a string) from the Lisp
+symbol SYMBOL. Used in cases where no parameter name is
+provided."
+ ;; we just downcase the symbol's name
+ (string-downcase symbol))
+
+(defun convert-parameter (argument type)
+ "Converts the string ARGUMENT to TYPE where TYPE is one of the
+symbols STRING, CHARACTERS, INTEGER, KEYWORD, or BOOLEAN - or
+otherwise a function designator for a function of one argument.
+ARGUMENT can also be NIL in which case this function also returns
+NIL unconditionally."
+ (when (listp argument)
+ ;; this if for the case that ARGUMENT is NIL or the result of a
+ ;; file upload
+ (return-from convert-parameter argument))
+ (case type
+ (string argument)
+ (character (and (= (length argument) 1)
+ (char argument 0)))
+ (integer (ignore-errors (parse-integer argument :junk-allowed t)))
+ (keyword (make-keyword argument :destructivep nil))
+ (boolean t)
+ (otherwise (funcall type argument))))
+
+(defun compute-simple-parameter (parameter-name type parameter-reader)
+ "Retrieves the parameter named PARAMETER-NAME using the reader
+PARAMETER-READER and converts it to TYPE."
+ (convert-parameter (funcall parameter-reader parameter-name) type))
+
+(defun compute-list-parameter (parameter-name type parameters)
+ "Retrieves all parameters from PARAMETERS which are named
+PARAMETER-NAME, converts them to TYPE, and returns a list of
+them."
+ (loop for (name . value) in parameters
+ when (string= name parameter-name)
+ collect (convert-parameter value type)))
+
+(defun compute-array-parameter (parameter-name type parameters)
+ "Retrieves all parameters from PARAMETERS which are named like
+\"PARAMETER-NAME[N]\" \(where N is a non-negative integer),
+converts them to TYPE, and returns an array where the Nth element
+is the corresponding value."
+ ;; see <http://common-lisp.net/pipermail/tbnl-devel/2006-September/000660.html>
+ #+:sbcl (declare (sb-ext:muffle-conditions warning))
+ (let* ((index-value-list
+ (loop for (full-name . value) in parameters
+ for index = (register-groups-bind (name index-string)
+ ("^(.*)\\[(\\d+)\\]$" full-name)
+ (when (string= name parameter-name)
+ (parse-integer index-string)))
+ when index
+ collect (cons index (convert-parameter value type))))
+ (array (make-array (1+ (reduce #'max index-value-list
+ :key #'car
+ :initial-value -1))
+ :initial-element nil)))
+ (loop for (index . value) in index-value-list
+ do (setf (aref array index) value))
+ array))
+
+(defun compute-hash-table-parameter (parameter-name type parameters key-type test-function)
+ "Retrieves all parameters from PARAMETERS which are named like
+\"PARAMETER-NAME{FOO}\" \(where FOO is any sequence of characters
+not containing curly brackets), converts them to TYPE, and
+returns a hash table with test function TEST-FUNCTION where the
+corresponding value is associated with the key FOO \(converted to
+KEY-TYPE)."
+ (let ((hash-table (make-hash-table :test test-function)))
+ (loop for (full-name . value) in parameters
+ for key = (register-groups-bind (name key-string)
+ ("^(.*){([^{}]+)}$" full-name)
+ (when (string= name parameter-name)
+ (convert-parameter key-string key-type)))
+ when key
+ do (setf (gethash key hash-table)
+ (convert-parameter value type)))
+ hash-table))
+
+(defun compute-parameter (parameter-name parameter-type request-type)
+ "Computes and returns the parameter\(s) called PARAMETER-NAME
+and converts it/them according to the value of PARAMETER-TYPE.
+REQUEST-TYPE is one of :GET, :POST, or :BOTH."
+ (when (member parameter-type '(list array hash-table))
+ (setq parameter-type (list parameter-type 'string)))
+ (let ((parameter-reader (ecase request-type
+ (:get #'get-parameter)
+ (:post #'post-parameter)
+ (:both #'parameter)))
+ (parameters (and (listp parameter-type)
+ (case request-type
+ (:get (get-parameters))
+ (:post (post-parameters))
+ (:both (append (get-parameters) (post-parameters)))))))
+ (cond ((atom parameter-type)
+ (compute-simple-parameter parameter-name parameter-type parameter-reader))
+ ((and (null (cddr parameter-type))
+ (eq (first parameter-type) 'list))
+ (compute-list-parameter parameter-name (second parameter-type) parameters))
+ ((and (null (cddr parameter-type))
+ (eq (first parameter-type) 'array))
+ (compute-array-parameter parameter-name (second parameter-type) parameters))
+ ((and (null (cddddr parameter-type))
+ (eq (first parameter-type) 'hash-table))
+ (compute-hash-table-parameter parameter-name (second parameter-type) parameters
+ (or (third parameter-type) 'string)
+ (or (fourth parameter-type) 'equal)))
+ (t (error "Don't know what to do with parameter type ~S." parameter-type)))))
+
+(defun make-defun-parameter (description default-parameter-type default-request-type)
+ "Creates a keyword parameter to be used by DEFINE-EASY-HANDLER.
+DESCRIPTION is one of the elements of DEFINE-EASY-HANDLER's
+LAMBDA-LIST and DEFAULT-PARAMETER-TYPE and DEFAULT-REQUEST-TYPE
+are the global default values."
+ (when (atom description)
+ (setq description (list description)))
+ (destructuring-bind (parameter-name &key (real-name (compute-real-name parameter-name))
+ parameter-type init-form request-type)
+ description
+ `(,parameter-name (or (and (boundp '*request*)
+ (compute-parameter ,real-name
+ ,(or parameter-type default-parameter-type)
+ ,(or request-type default-request-type)))
+ ,init-form))))
+
+(defmacro define-easy-handler (description lambda-list &body body)
+ "Defines a handler with the body BODY and optionally registers
+it with a URI so that it will be found by DISPATCH-EASY-HANDLERS.
+DESCRIPTION is either a symbol NAME or a list matching the
+destructuring lambda list
+
+ (name &key uri server-names default-parameter-type default-request-type).
+
+LAMBDA-LIST is a list the elements of which are either a symbol
+VAR or a list matching the destructuring lambda list
+
+ (var &key real-name parameter-type init-form request-type).
+
+The resulting handler will be a Lisp function with the name NAME
+and keyword parameters named by the VAR symbols. Each VAR will
+be bound to the value of the GET or POST parameter called
+REAL-NAME \(a string) before BODY is executed. If REAL-NAME is
+not provided, it will be computed by downcasing the symbol name
+of VAR.
+
+If URI \(which is evaluated) is provided, then it must be a string or
+a function designator for a function of one argument. In this case,
+the handler will be returned by DISPATCH-EASY-HANDLERS, if URI is a
+string and the script name of a request is URI, or if URI designates a
+function and applying this function to the current request object
+returns a true value.
+
+SERVER-NAMES \(which is evaluated) can be a list of symbols which
+means that the handler will be returned by DISPATCH-EASY-HANDLERS in
+servers which have one of these names \(see SERVER-NAME).
+SERVER-NAMES can also be the symbol T which means that the handler
+will be returned by DISPATCH-EASY-HANDLERS in every server.
+
+Whether the GET or POST parameter \(or both) will be taken into
+consideration, depends on REQUEST-TYPE which can
+be :GET, :POST, :BOTH, or NIL. In the last case, the value of
+DEFAULT-REQUEST-TYPE \(the default of which is :BOTH) will be
+used.
+
+The value of VAR will usually be a string \(unless it resulted from a
+file upload in which case it won't be converted at all), but if
+PARAMETER-TYPE \(which is evaluated) is provided, the string will be
+converted to another Lisp type by the following rules:
+
+If the corresponding GET or POST parameter wasn't provided by the
+client, VAR's value will be NIL. If PARAMETER-TYPE is 'STRING, VAR's
+value remains as is. If PARAMETER-TYPE is 'INTEGER and the parameter
+string consists solely of decimal digits, VAR's value will be the
+corresponding integer, otherwise NIL. If PARAMETER-TYPE is 'KEYWORD,
+VAR's value will be the keyword obtained by interning the upcased
+parameter string into the keyword package. If PARAMETER-TYPE is
+'CHARACTER and the parameter string is of length one, VAR's value will
+be the single character of this string, otherwise NIL. If
+PARAMETER-TYPE is 'BOOLEAN, VAR's value will always be T \(unless it
+is NIL by the first rule above, of course). If PARAMETER-TYPE is any
+other atom, it is supposed to be a function designator for a unary
+function which will be called to convert the string to something else.
+
+Those were the rules for `simple' types, but PARAMETER-TYPE can
+also be a list starting with one of the symbols LIST, ARRAY, or
+HASH-TABLE. The second value of the list must always be a simple
+parameter type as in the last paragraph - we'll call it the
+`inner type' below.
+
+In the case of 'LIST, all GET/POST parameters called REAL-NAME
+will be collected, converted to the inner type, and assembled
+into a list which will be the value of VAR.
+
+In the case of 'ARRAY, all GET/POST parameters which have a name
+like the result of
+
+ (format nil \"~A[~A]\" real-name n)
+
+where N is a non-negative integer, will be assembled into an
+array where the Nth element will be set accordingly, after
+conversion to the inner type. The array, which will become the
+value of VAR, will be big enough to hold all matching parameters,
+but not bigger. Array elements not set as described above will
+be NIL. Note that VAR will always be bound to an array, which
+may be empty, so it will never be NIL, even if no appropriate
+GET/POST parameters are found.
+
+The full form of a 'HASH-TABLE parameter type is
+
+ (hash-table inner-type key-type test-function),
+
+but KEY-TYPE and TEST-FUNCTION can be left out in which case they
+default to 'STRING and 'EQUAL, respectively. For this parameter
+type, all GET/POST parameters which have a name like the result
+of
+
+ (format nil \"~A{~A}\" real-name key)
+
+\(where KEY is a string that doesn't contain curly brackets) will
+become the values \(after conversion to INNER-TYPE) of a hash
+table with test function TEST-FUNCTION where KEY \(after
+conversion to KEY-TYPE) will be the corresponding key. Note that
+VAR will always be bound to a hash table, which may be empty, so
+it will never be NIL, even if no appropriate GET/POST parameters
+are found.
+
+To make matters even more complicated, the three compound
+parameter types also have an abbreviated form - just one of the
+symbols LIST, ARRAY, or HASH-TABLE. In this case, the inner type
+will default to 'STRING.
+
+If PARAMETER-TYPE is not provided or NIL, DEFAULT-PARAMETER-TYPE
+\(the default of which is 'STRING) will be used instead.
+
+If the result of the computations above would be that VAR would
+be bound to NIL, then INIT-FORM \(if provided) will be evaluated
+instead, and VAR will be bound to the result of this evaluation.
+
+Handlers built with this macro are constructed in such a way that
+the resulting Lisp function is useful even outside of
+Hunchentoot. Specifically, all the parameter computations above
+will only happen if *REQUEST* is bound, i.e. if we're within a
+Hunchentoot request. Otherwise, VAR will always be bound to the
+result of evaluating INIT-FORM unless a corresponding keyword
+argument is provided."
+ (when (atom description)
+ (setq description (list description)))
+ (destructuring-bind (name &key uri (server-names t)
+ (default-parameter-type ''string)
+ (default-request-type :both))
+ description
+ `(progn
+ ,@(when uri
+ (list
+ (with-rebinding (uri)
+ `(progn
+ (setq *easy-handler-alist*
+ (delete-if (lambda (list)
+ (or (equal ,uri (first list))
+ (eq ',name (third list))))
+ *easy-handler-alist*))
+ (push (list ,uri ,server-names ',name) *easy-handler-alist*)))))
+ (defun ,name (&key ,@(loop for part in lambda-list
+ collect (make-defun-parameter part
+ default-parameter-type
+ default-request-type)))
+ ,@body))))
+
+;; help the LispWorks IDE to find these definitions
+#+:lispworks
+(dspec:define-form-parser define-easy-handler (description)
+ `(,define-easy-handler ,(if (atom description) description (first description))))
+
+#+:lispworks
+(dspec:define-dspec-alias define-easy-handler (name)
+ `(defun ,name))
+
+(defun dispatch-easy-handlers (request)
+ "This is a dispatcher which returns the appropriate handler
+defined with DEFINE-EASY-HANDLER, if there is one."
+ (loop for (uri server-names easy-handler) in *easy-handler-alist*
+ when (and (or (eq server-names t)
+ (find (server-name *server*) server-names :test #'eq))
+ (cond ((stringp uri)
+ (string= (script-name request) uri))
+ (t (funcall uri request))))
+ do (return easy-handler)))
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/easy-handlers.lisp
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/headers.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/headers.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/headers.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,320 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/headers.lisp,v 1.24 2007/09/24 13:43:45 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(defun maybe-write-to-header-stream (key &optional value)
+ (when *header-stream*
+ (format *header-stream* "~A~@[: ~A~]~%" key
+ (and value (regex-replace-all "[\\r\\n]" value " ")))
+ (force-output *header-stream*)))
+
+(defun compute-length (content)
+ "Computes and returns the length of CONTENT in octets. Returns as a
+second value CONTENT as a vector of octets. The result depends on the
+external format of *REPLY*."
+ (when (null content)
+ (return-from compute-length))
+ (when (stringp content)
+ (setq content
+ (string-to-octets content :external-format (reply-external-format))))
+ (values (length content) content))
+
+(defmethod write-header-line ((mod-lisp-p (eql nil)) key value)
+ "Accepts strings KEY and VALUE and writes them directly to the
+client as an HTTP header line."
+ (write-string key *hunchentoot-stream*)
+ (write-string ": " *hunchentoot-stream*)
+ ;; remove line breaks
+ (write-string (regex-replace-all "[\\r\\n]" value " ") *hunchentoot-stream*)
+ (write-string +crlf+ *hunchentoot-stream*))
+
+(defmethod write-header-line (mod-lisp-p key value)
+ "Accepts strings KEY and VALUE and writes them, one line at a time,
+to the mod_lisp socket stream."
+ (write-line key *hunchentoot-stream*)
+ ;; remove line breaks
+ (write-line (regex-replace-all "[\\r\\n]" value " ") *hunchentoot-stream*))
+
+(defmethod write-header-line :after (mod-lisp-p key value)
+ (declare (ignorable mod-lisp-p))
+ (maybe-write-to-header-stream key value))
+
+(defun start-output (&optional (content nil content-provided-p))
+ "Sends all headers and maybe the content body to
+*HUNCHENTOOT-STREAM*. Returns immediately and does nothing if called
+more than once per request. Handles the supported return codes
+accordingly. Called by PROCESS-REQUEST and/or SEND-HEADERS. Returns
+the stream to write to."
+ ;; send headers only once
+ (when *headers-sent*
+ (return-from start-output))
+ (setq *headers-sent* t)
+ ;; read post data to clear stream
+ (raw-post-data)
+ (let* ((mod-lisp-p (server-mod-lisp-p *server*))
+ (return-code (return-code))
+ (chunkedp (and (server-output-chunking-p *server*)
+ (eq (server-protocol) :http/1.1)
+ ;; only turn chunking on if the content
+ ;; length is unknown at this point...
+ (null (or (content-length) content-provided-p))
+ ;; ...AND if the return code isn't one where
+ ;; Hunchentoot (or a user error handler) sends its
+ ;; own content
+ (member return-code *approved-return-codes*)))
+ (reason-phrase (reason-phrase return-code))
+ (request-method (request-method))
+ (head-request-p (eq request-method :head))
+ content-modified-p)
+ (unless mod-lisp-p
+ (multiple-value-bind (keep-alive-p keep-alive-requested-p)
+ (keep-alive-p)
+ (when keep-alive-p
+ (setq keep-alive-p
+ ;; use keep-alive if there's a way for the client to
+ ;; determine when all content is sent (or if there
+ ;; is no content)
+ (or chunkedp
+ head-request-p
+ (eq (return-code) +http-not-modified+)
+ (content-length)
+ content)))
+ ;; now set headers for keep-alive and chunking
+ (when chunkedp
+ (setf (header-out "Transfer-Encoding") "chunked"))
+ (cond (keep-alive-p
+ (setf *close-hunchentoot-stream* nil)
+ (when (or (not (eq (server-protocol) :http/1.1))
+ keep-alive-requested-p)
+ ;; persistent connections are implicitly assumed for
+ ;; HTTP/1.1, but we return a 'Keep-Alive' header if the
+ ;; client has explicitly asked for one
+ (setf (header-out "Connection") "Keep-Alive"
+ (header-out "Keep-Alive")
+ (format nil "timeout=~D" (server-read-timeout *server*)))))
+ (t (setf (header-out "Connection") "Close"))))
+ (unless (and (header-out-set-p "Server")
+ (null (header-out "Server")))
+ (setf (header-out "Server") (or (header-out "Server")
+ (server-name-header))))
+ (setf (header-out "Date") (rfc-1123-date)))
+ (unless reason-phrase
+ (setq content (escape-for-html
+ (format nil "Unknown http return code: ~A" return-code))
+ content-modified-p t
+ return-code +http-internal-server-error+
+ reason-phrase (reason-phrase return-code)))
+ (unless (or (not *handle-http-errors-p*)
+ (member return-code *approved-return-codes*))
+ ;; call error handler, if any - should return NIL if it can't
+ ;; handle the error
+ (let (error-handled-p)
+ (when *http-error-handler*
+ (setq error-handled-p (funcall *http-error-handler* return-code)
+ content (or error-handled-p content)
+ content-modified-p (or content-modified-p error-handled-p)))
+ ;; handle common return codes other than 200, which weren't
+ ;; handled by the error handler
+ (unless error-handled-p
+ (setf (content-type)
+ "text/html; charset=iso-8859-1"
+ content-modified-p t
+ content
+ (format nil "<html><head><title>~D ~A</title></head><body><h1>~:*~A</h1>~A<p><hr>~A</p></body></html>"
+ return-code reason-phrase
+ (case return-code
+ ((#.+http-internal-server-error+) content)
+ ((#.+http-moved-temporarily+ #.+http-moved-permanently+)
+ (format nil "The document has moved <a href='~A'>here</a>"
+ (header-out "Location")))
+ ((#.+http-authorization-required+)
+ "The server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials \(e.g., bad password), or your browser doesn't understand how to supply the credentials required.")
+ ((#.+http-forbidden+)
+ (format nil "You don't have permission to access ~A on this server."
+ (script-name)))
+ ((#.+http-not-found+)
+ (format nil "The requested URL ~A was not found on this server."
+ (script-name)))
+ ((#.+http-bad-request+)
+ "Your browser sent a request that this server could not understand.")
+ (otherwise ""))
+ (address-string))))))
+ ;; start with status line
+ (cond (mod-lisp-p
+ (write-header-line t "Status" (format nil "~D ~A" return-code reason-phrase)))
+ (t
+ (let ((first-line
+ (format nil "HTTP/1.1 ~D ~A" return-code reason-phrase)))
+ (write-string first-line *hunchentoot-stream*)
+ (write-string +crlf+ *hunchentoot-stream*)
+ (maybe-write-to-header-stream first-line))))
+ (when (and (stringp content)
+ (not content-modified-p)
+ (starts-with-one-of-p (or (content-type) "")
+ *content-types-for-url-rewrite*))
+ ;; if the Content-Type header starts with one of the strings
+ ;; in *CONTENT-TYPES-FOR-URL-REWRITE* then maybe rewrite the
+ ;; content
+ (setq content (maybe-rewrite-urls-for-session content)))
+ (let ((content-length (content-length)))
+ (unless content-length
+ (multiple-value-setq (content-length content) (compute-length content)))
+ ;; write the corresponding headers for the content
+ (when content-length
+ (write-header-line mod-lisp-p "Content-Length" (format nil "~D" content-length))
+ (when mod-lisp-p
+ (write-header-line t "Lisp-Content-Length"
+ (cond (head-request-p "0")
+ (t (format nil "~D" content-length))))
+ (write-header-line t "Keep-Socket" "1")
+ (setq *close-hunchentoot-stream* nil)))
+ (when-let (content-type (content-type))
+ (write-header-line mod-lisp-p "Content-Type" content-type))
+ ;; write all headers from the REPLY object
+ (loop for (key . value) in (headers-out)
+ when value
+ do (write-header-line mod-lisp-p (string-capitalize key) value))
+ ;; now the cookies
+ (loop for (nil . cookie) in (cookies-out)
+ do (write-header-line mod-lisp-p "Set-Cookie" (stringify-cookie cookie)))
+ (when mod-lisp-p
+ ;; send log messages to mod_lisp
+ (loop for (log-level . message) in (reverse (log-messages *reply*))
+ do (write-header-line t (case log-level
+ ((:emerg) "Log-Emerg")
+ ((:alert) "Log-Alert")
+ ((:crit) "Log-Crit")
+ ((:error) "Log-Error")
+ ((:warning) "Log-Warning")
+ ((:notice) "Log-Notice")
+ ((:info) "Log-Info")
+ ((:debug) "Log-Debug")
+ (otherwise "Log"))
+ message)))
+ ;; all headers sent
+ (cond (mod-lisp-p
+ (write-line "end" *hunchentoot-stream*)
+ (maybe-write-to-header-stream "end"))
+ (t
+ (write-string +crlf+ *hunchentoot-stream*)
+ (maybe-write-to-header-stream "")))
+ ;; access log message
+ (when (and *show-access-log-messages*
+ (not (server-use-apache-log-p *server*)))
+ (ignore-errors
+ (log-message nil "~:[-~@[ (~A)~]~;~:*~A~@[ (~A)~]~] ~:[-~;~:*~A~] \"~A ~A~@[?~A~] ~A\" ~A ~:[~*-~;~D~] \"~:[-~;~:*~A~]\" \"~:[-~;~:*~A~]\""
+ (remote-addr) (header-in :x-forwarded-for)
+ (authorization) request-method (script-name)
+ (query-string) (server-protocol)
+ return-code content content-length
+ (referer) (user-agent)))))
+ (setf (flexi-stream-external-format *hunchentoot-stream*) (reply-external-format))
+ ;; now optional content
+ (unless (or (null content) head-request-p)
+ (ignore-errors
+ (write-sequence content *hunchentoot-stream*)))
+ (when chunkedp
+ ;; turn chunking on after the headers have been sent
+ (setf (chunked-stream-output-chunking-p
+ (flexi-stream-stream *hunchentoot-stream*)) t))
+ *hunchentoot-stream*))
+
+(defun send-headers ()
+ "Sends the initial status line and all headers as determined by
+the REPLY object *REPLY*. Returns a stream to which the body of
+the reply can be written. Once this function has been called,
+further changes to *REPLY* don't have any effect. Also,
+automatic handling of errors \(i.e. sending the corresponding
+status code to the browser, etc.) is turned off for this request.
+If your handlers return the full body as a string or as an array
+of octets you should NOT call this function."
+ (start-output))
+
+(defun get-request-data ()
+ "Reads incoming headers from mod_lisp or directly from the client
+via *HUNCHENTOOT-STREAM*. Returns as multiple values the headers as
+an alist, the stream to read the request body from, the method, the
+URI, and the protocol of the request. The last three values are only
+returned if we're not behind mod_lisp."
+ (ignore-errors
+ (let* ((mod-lisp-p (server-mod-lisp-p *server*))
+ (first-line (if mod-lisp-p
+ (read-line *hunchentoot-stream* nil nil)
+ (cl:handler-case
+ (read-line* *hunchentoot-stream*)
+ ((or end-of-file
+ #+:sbcl sb-sys:io-timeout
+ #+:cmu sys:io-timeout
+ #+:allegro excl:socket-error) ()
+ nil)))))
+ (cond ((null first-line)
+ ;; socket closed - return immediately
+ nil)
+ (mod-lisp-p
+ ;; we're behind mod_lisp, so we read alternating
+ ;; key/value lines
+ (let ((second-line (read-line *hunchentoot-stream* t)))
+ (maybe-write-to-header-stream first-line second-line)
+ (let* ((headers
+ (loop for key = (read-line *hunchentoot-stream* nil nil)
+ while (and key (string-not-equal key "end"))
+ for value = (read-line *hunchentoot-stream* t)
+ collect (cons (make-keyword key) value)
+ do (maybe-write-to-header-stream key value)))
+ (content-length (cdr (assoc :content-length headers))))
+ ;; add contents of first two lines
+ (push (cons (make-keyword first-line) second-line) headers)
+ (values (delete-duplicates headers :test #'eq :key #'car)
+ (and (or content-length
+ (server-input-chunking-p *server*))
+ *hunchentoot-stream*)))))
+ (t
+ ;; we're a stand-alone web server, so we use Chunga to
+ ;; read the headers
+ (destructuring-bind (method url-string &optional protocol)
+ (split "\\s+" first-line :limit 3)
+ (maybe-write-to-header-stream first-line)
+ (let ((headers (and protocol (read-http-headers *hunchentoot-stream*
+ *header-stream*))))
+ (unless protocol (setq protocol "HTTP/0.9"))
+ (when (equalp (cdr (assoc :expect headers)) "100-continue")
+ ;; handle 'Expect: 100-continue' header
+ (let ((continue-line
+ (format nil "HTTP/1.1 ~D ~A"
+ +http-continue+
+ (reason-phrase +http-continue+))))
+ (write-string continue-line *hunchentoot-stream*)
+ (write-string +crlf+ *hunchentoot-stream*)
+ (write-string +crlf+ *hunchentoot-stream*)
+ (force-output *hunchentoot-stream*)
+ (maybe-write-to-header-stream continue-line)
+ (maybe-write-to-header-stream "")))
+ (values headers *hunchentoot-stream* (make-keyword method) url-string
+ (make-keyword (string-trim '(#\Space #\Tab #\NewLine #\Return) protocol))))))))))
\ No newline at end of file
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/headers.lisp
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/hunchentoot-test.asd
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/hunchentoot-test.asd 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/hunchentoot-test.asd 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,35 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/hunchentoot-test.asd,v 1.2 2007/01/01 23:50:30 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(asdf:defsystem :hunchentoot-test
+ :components ((:module "test"
+ :serial t
+ :components ((:file "packages")
+ (:file "test"))))
+ :depends-on (:hunchentoot :cl-who))
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/hunchentoot-test.asd
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/hunchentoot.asd
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/hunchentoot.asd 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/hunchentoot.asd 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,79 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/hunchentoot.asd,v 1.52 2007/11/15 07:29:56 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :cl-user)
+
+(defpackage :hunchentoot-asd
+ (:use :cl :asdf))
+
+(in-package :hunchentoot-asd)
+
+(defvar *hunchentoot-version* "0.14.7"
+ "A string denoting the current version of Hunchentoot. Used
+for diagnostic output.")
+
+(export '*hunchentoot-version*)
+
+(asdf:defsystem :hunchentoot
+ :serial t
+ :version #.*hunchentoot-version*
+ :depends-on (:chunga
+ :cl-base64
+ :cl-ppcre
+ #-(or :lispworks :hunchentoot-no-ssl) :cl+ssl
+ :md5
+ :rfc2388
+ #+:sbcl :sb-bsd-sockets
+ #+:sbcl :sb-posix
+ #+:openmcl :acl-compat
+ :url-rewrite)
+ :components ((:file "packages")
+ (:file "conditions")
+ #+:allegro (:file "port-acl")
+ #+:cmu (:file "port-cmu")
+ #+:lispworks (:file "port-lw")
+ #+:openmcl (:file "port-mcl")
+ #+:sbcl (:file "port-sbcl")
+ (:file "specials")
+ (:file "mime-types")
+ (:file "util")
+ (:file "log")
+ (:file "cookie")
+ (:file "reply")
+ (:file "request")
+ (:file "session")
+ (:file "misc")
+ (:file "easy-handlers")
+ (:file "headers")
+ #+(and :allegro :unix) (:file "unix-acl")
+ #+(and :cmu :unix) (:file "unix-cmu")
+ #+(and :lispworks :unix) (:file "unix-lw")
+ #+(and :openmcl :unix) (:file "unix-mcl")
+ #+(and :sbcl :unix (not :win32)) (:file "unix-sbcl")
+ (:file "server")))
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/hunchentoot.asd
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/log.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/log.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/log.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,93 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/log.lisp,v 1.9 2007/10/19 23:51:32 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(defgeneric log-message (log-level fmt &rest args))
+
+(defmethod log-message (log-level fmt &rest args)
+ "Sends a formatted message to Apache's error log when the data gets
+sent to Apache/mod_lisp and SERVER-USE-APACHE-LOG-P is true, otherwise
+logs to the file denoted by LOG-FILE. FMT and ARGS are as in FORMAT.
+LOG-LEVEL is a keyword denoting the corresponding Apache error level."
+ (let ((message (apply #'format nil fmt args)))
+ (cond ((and (boundp '*server*)
+ (server-mod-lisp-p *server*)
+ (server-use-apache-log-p *server*))
+ (with-input-from-string (s message)
+ (loop with prolog = (case *log-prefix*
+ ((nil) "")
+ ((t) "[Hunchentoot] ")
+ (otherwise (format nil "[~A] " *log-prefix*)))
+ for line = (read-line s nil nil)
+ while line
+ do (push (cons log-level
+ (format nil "~A~A" prolog line))
+ (slot-value *reply* 'log-messages)))))
+ (t (with-lock (*log-file-lock*)
+ (ignore-errors
+ (unless *log-file-stream*
+ (let ((log-file-stream
+ (open (ensure-directories-exist *log-file*)
+ :direction :output
+ :element-type 'octet
+ :if-does-not-exist :create
+ :if-exists :append
+ #+:openmcl #+:openmcl
+ :sharing :lock)))
+ (setq *log-file-stream*
+ (make-flexi-stream log-file-stream
+ :external-format +utf-8+))))
+ (handler-case
+ (format *log-file-stream*
+ "[~A~@[ [~A]~]] ~A~%" (iso-time) log-level message)
+ (error ()
+ (format *log-file-stream* "[~A [EMERG]] A message could not be logged!"
+ (iso-time))))
+ (force-output *log-file-stream*))))))
+ (values))
+
+(defun log-message* (fmt &rest args)
+ "Same as LOG-MESSAGE* but with the default log level \(as
+defined by *DEFAULT-LOG-LEVEL*)."
+ (apply #'log-message *default-log-level* fmt args))
+
+(defun log-file ()
+ "Returns the log file which is currently used."
+ *log-file*)
+
+(defun (setf log-file) (pathspec)
+ "Sets the log file which is to be used."
+ (with-lock (*log-file-lock*)
+ (when *log-file-stream*
+ (ignore-errors
+ (close *log-file-stream*))
+ (setq *log-file-stream* nil))
+ (setq *log-file* pathspec)))
+
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/mime-types.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/mime-types.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/mime-types.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,362 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/mime-types.lisp,v 1.3 2007/01/01 23:50:30 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(defparameter *mime-type-list* '(("application/andrew-inset" "ez")
+ ("application/cu-seeme" "cu")
+ ("application/dsptype" "tsp")
+ ("application/futuresplash" "spl")
+ ("application/hta" "hta")
+ ("application/java-archive" "jar")
+ ("application/java-serialized-object" "ser")
+ ("application/java-vm" "class")
+ ("application/mac-binhex40" "hqx")
+ ("application/mac-compactpro" "cpt")
+ ("application/mathematica" "nb")
+ ("application/msaccess" "mdb")
+ ("application/msword" "doc" "dot")
+ ("application/octet-stream" "bin")
+ ("application/oda" "oda")
+ ("application/ogg" "ogg")
+ ("application/pdf" "pdf")
+ ("application/pgp-keys" "key")
+ ("application/pgp-signature" "pgp")
+ ("application/pics-rules" "prf")
+ ("application/postscript" "ps" "ai" "eps")
+ ("application/rar" "rar")
+ ("application/rdf+xml" "rdf")
+ ("application/rss+xml" "rss")
+ ("application/smil" "smi" "smil")
+ ("application/wordperfect" "wpd")
+ ("application/wordperfect5.1" "wp5")
+ ("application/xhtml+xml" "xhtml" "xht")
+ ("application/xml" "fo" "xml" "xsl")
+ ("application/zip" "zip")
+ ("application/vnd.cinderella" "cdy")
+ ("application/vnd.mozilla.xul+xml" "xul")
+ ("application/vnd.ms-excel" "xls" "xlb" "xlt")
+ ("application/vnd.ms-pki.seccat" "cat")
+ ("application/vnd.ms-pki.stl" "stl")
+ ("application/vnd.ms-powerpoint" "ppt" "pps")
+ ("application/vnd.oasis.opendocument.chart" "odc")
+ ("application/vnd.oasis.opendocument.database" "odb")
+ ("application/vnd.oasis.opendocument.formula" "odf")
+ ("application/vnd.oasis.opendocument.graphics" "odg")
+ ("application/vnd.oasis.opendocument.graphics-template" "otg")
+ ("application/vnd.oasis.opendocument.image" "odi")
+ ("application/vnd.oasis.opendocument.presentation" "odp")
+ ("application/vnd.oasis.opendocument.presentation-template" "otp")
+ ("application/vnd.oasis.opendocument.spreadsheet" "ods")
+ ("application/vnd.oasis.opendocument.spreadsheet-template" "ots")
+ ("application/vnd.oasis.opendocument.text" "odt")
+ ("application/vnd.oasis.opendocument.text-master" "odm")
+ ("application/vnd.oasis.opendocument.text-template" "ott")
+ ("application/vnd.oasis.opendocument.text-web" "oth")
+ ("application/vnd.rim.cod" "cod")
+ ("application/vnd.smaf" "mmf")
+ ("application/vnd.stardivision.calc" "sdc")
+ ("application/vnd.stardivision.draw" "sda")
+ ("application/vnd.stardivision.impress" "sdd" "sdp")
+ ("application/vnd.stardivision.math" "smf")
+ ("application/vnd.stardivision.writer" "sdw" "vor")
+ ("application/vnd.stardivision.writer-global" "sgl")
+ ("application/vnd.sun.xml.calc" "sxc")
+ ("application/vnd.sun.xml.calc.template" "stc")
+ ("application/vnd.sun.xml.draw" "sxd")
+ ("application/vnd.sun.xml.draw.template" "std")
+ ("application/vnd.sun.xml.impress" "sxi")
+ ("application/vnd.sun.xml.impress.template" "sti")
+ ("application/vnd.sun.xml.math" "sxm")
+ ("application/vnd.sun.xml.writer" "sxw")
+ ("application/vnd.sun.xml.writer.global" "sxg")
+ ("application/vnd.sun.xml.writer.template" "stw")
+ ("application/vnd.symbian.install" "sis")
+ ("application/vnd.visio" "vsd")
+ ("application/vnd.wap.wbxml" "wbxml")
+ ("application/vnd.wap.wmlc" "wmlc")
+ ("application/vnd.wap.wmlscriptc" "wmlsc")
+ ("application/x-123" "wk")
+ ("application/x-abiword" "abw")
+ ("application/x-apple-diskimage" "dmg")
+ ("application/x-bcpio" "bcpio")
+ ("application/x-bittorrent" "torrent")
+ ("application/x-cdf" "cdf")
+ ("application/x-cdlink" "vcd")
+ ("application/x-chess-pgn" "pgn")
+ ("application/x-cpio" "cpio")
+ ("application/x-csh" "csh")
+ ("application/x-debian-package" "deb" "udeb")
+ ("application/x-director" "dcr" "dir" "dxr")
+ ("application/x-dms" "dms")
+ ("application/x-doom" "wad")
+ ("application/x-dvi" "dvi")
+ ("application/x-flac" "flac")
+ ("application/x-font" "pfa" "pfb" "gsf" "pcf")
+ ("application/x-freemind" "mm")
+ ("application/x-futuresplash" "spl")
+ ("application/x-gnumeric" "gnumeric")
+ ("application/x-go-sgf" "sgf")
+ ("application/x-graphing-calculator" "gcf")
+ ("application/x-gtar" "gtar" "tgz" "taz")
+ ("application/x-hdf" "hdf")
+ ("application/x-httpd-php" "phtml" "pht" "php")
+ ("application/x-httpd-php-source" "phps")
+ ("application/x-httpd-php3" "php3")
+ ("application/x-httpd-php3-preprocessed" "php3p")
+ ("application/x-httpd-php4" "php4")
+ ("application/x-ica" "ica")
+ ("application/x-internet-signup" "ins" "isp")
+ ("application/x-iphone" "iii")
+ ("application/x-iso9660-image" "iso")
+ ("application/x-java-jnlp-file" "jnlp")
+ ("application/x-javascript" "js")
+ ("application/x-jmol" "jmz")
+ ("application/x-kchart" "chrt")
+ ("application/x-killustrator" "kil")
+ ("application/x-koan" "skp" "skd" "skt" "skm")
+ ("application/x-kpresenter" "kpr" "kpt")
+ ("application/x-kspread" "ksp")
+ ("application/x-kword" "kwd" "kwt")
+ ("application/x-latex" "latex")
+ ("application/x-lha" "lha")
+ ("application/x-lzh" "lzh")
+ ("application/x-lzx" "lzx")
+ ("application/x-maker" "frm" "maker" "frame" "fm" "fb" "book" "fbdoc")
+ ("application/x-mif" "mif")
+ ("application/x-ms-wmd" "wmd")
+ ("application/x-ms-wmz" "wmz")
+ ("application/x-msdos-program" "com" "exe" "bat" "dll")
+ ("application/x-msi" "msi")
+ ("application/x-netcdf" "nc")
+ ("application/x-ns-proxy-autoconfig" "pac")
+ ("application/x-nwc" "nwc")
+ ("application/x-object" "o")
+ ("application/x-oz-application" "oza")
+ ("application/x-pkcs7-certreqresp" "p7r")
+ ("application/x-pkcs7-crl" "crl")
+ ("application/x-python-code" "pyc" "pyo")
+ ("application/x-quicktimeplayer" "qtl")
+ ("application/x-redhat-package-manager" "rpm")
+ ("application/x-sh" "sh")
+ ("application/x-shar" "shar")
+ ("application/x-shockwave-flash" "swf" "swfl")
+ ("application/x-stuffit" "sit")
+ ("application/x-sv4cpio" "sv4cpio")
+ ("application/x-sv4crc" "sv4crc")
+ ("application/x-tar" "tar")
+ ("application/x-tcl" "tcl")
+ ("application/x-tex-gf" "gf")
+ ("application/x-tex-pk" "pk")
+ ("application/x-texinfo" "texinfo" "texi")
+ ("application/x-trash" "~%" "" "bak" "old" "sik")
+ ("application/x-troff" "tt" "r" "roff")
+ ("application/x-troff-man" "man")
+ ("application/x-troff-me" "me")
+ ("application/x-troff-ms" "ms")
+ ("application/x-ustar" "ustar")
+ ("application/x-wais-source" "src")
+ ("application/x-wingz" "wz")
+ ("application/x-x509-ca-cert" "crt")
+ ("application/x-xcf" "xcf")
+ ("application/x-xfig" "fig")
+ ("application/x-xpinstall" "xpi")
+ ("audio/basic" "au" "snd")
+ ("audio/midi" "mid" "midi" "kar")
+ ("audio/mpeg" "mpga" "mpega" "mp2" "mp3" "m4a")
+ ("audio/mpegurl" "m3u")
+ ("audio/prs.sid" "sid")
+ ("audio/x-aiff" "aif" "aiff" "aifc")
+ ("audio/x-gsm" "gsm")
+ ("audio/x-mpegurl" "m3u")
+ ("audio/x-ms-wma" "wma")
+ ("audio/x-ms-wax" "wax")
+ ("audio/x-pn-realaudio" "ra" "rm" "ram")
+ ("audio/x-realaudio" "ra")
+ ("audio/x-scpls" "pls")
+ ("audio/x-sd2" "sd2")
+ ("audio/x-wav" "wav")
+ ("chemical/x-alchemy" "alc")
+ ("chemical/x-cache" "cac" "cache")
+ ("chemical/x-cache-csf" "csf")
+ ("chemical/x-cactvs-binary" "cbin" "cascii" "ctab")
+ ("chemical/x-cdx" "cdx")
+ ("chemical/x-cerius" "cer")
+ ("chemical/x-chem3d" "c3d")
+ ("chemical/x-chemdraw" "chm")
+ ("chemical/x-cif" "cif")
+ ("chemical/x-cmdf" "cmdf")
+ ("chemical/x-cml" "cml")
+ ("chemical/x-compass" "cpa")
+ ("chemical/x-crossfire" "bsd")
+ ("chemical/x-csml" "csml" "csm")
+ ("chemical/x-ctx" "ctx")
+ ("chemical/x-cxf" "cxf" "cef")
+ ("chemical/x-embl-dl-nucleotide" "emb" "embl")
+ ("chemical/x-galactic-spc" "spc")
+ ("chemical/x-gamess-input" "inp" "gam" "gamin")
+ ("chemical/x-gaussian-checkpoint" "fch" "fchk")
+ ("chemical/x-gaussian-cube" "cub")
+ ("chemical/x-gaussian-input" "gau" "gjc" "gjf")
+ ("chemical/x-gaussian-log" "gal")
+ ("chemical/x-gcg8-sequence" "gcg")
+ ("chemical/x-genbank" "gen")
+ ("chemical/x-hin" "hin")
+ ("chemical/x-isostar" "istr" "ist")
+ ("chemical/x-jcamp-dx" "jdx" "dx")
+ ("chemical/x-kinemage" "kin")
+ ("chemical/x-macmolecule" "mcm")
+ ("chemical/x-macromodel-input" "mmd" "mmod")
+ ("chemical/x-mdl-molfile" "mol")
+ ("chemical/x-mdl-rdfile" "rd")
+ ("chemical/x-mdl-rxnfile" "rxn")
+ ("chemical/x-mdl-sdfile" "sd" "sdf")
+ ("chemical/x-mdl-tgf" "tgf")
+ ("chemical/x-mmcif" "mcif")
+ ("chemical/x-mol2" "mol2")
+ ("chemical/x-molconn-Z" "b")
+ ("chemical/x-mopac-graph" "gpt")
+ ("chemical/x-mopac-input" "mop" "mopcrt" "mpc" "dat" "zmt")
+ ("chemical/x-mopac-out" "moo")
+ ("chemical/x-mopac-vib" "mvb")
+ ("chemical/x-ncbi-asn1" "asn")
+ ("chemical/x-ncbi-asn1-ascii" "prt" "ent")
+ ("chemical/x-ncbi-asn1-binary" "val" "aso")
+ ("chemical/x-ncbi-asn1-spec" "asn")
+ ("chemical/x-pdb" "pdb" "ent")
+ ("chemical/x-rosdal" "ros")
+ ("chemical/x-swissprot" "sw")
+ ("chemical/x-vamas-iso14976" "vms")
+ ("chemical/x-vmd" "vmd")
+ ("chemical/x-xtel" "xtel")
+ ("chemical/x-xyz" "xyz")
+ ("image/gif" "gif")
+ ("image/ief" "ief")
+ ("image/jpeg" "jpeg" "jpg" "jpe")
+ ("image/pcx" "pcx")
+ ("image/png" "png")
+ ("image/svg+xml" "svg" "svgz")
+ ("image/tiff" "tiff" "tif")
+ ("image/vnd.djvu" "djvu" "djv")
+ ("image/vnd.wap.wbmp" "wbmp")
+ ("image/x-cmu-raster" "ras")
+ ("image/x-coreldraw" "cdr")
+ ("image/x-coreldrawpattern" "pat")
+ ("image/x-coreldrawtemplate" "cdt")
+ ("image/x-corelphotopaint" "cpt")
+ ("image/x-icon" "ico")
+ ("image/x-jg" "art")
+ ("image/x-jng" "jng")
+ ("image/x-ms-bmp" "bmp")
+ ("image/x-photoshop" "psd")
+ ("image/x-portable-anymap" "pnm")
+ ("image/x-portable-bitmap" "pbm")
+ ("image/x-portable-graymap" "pgm")
+ ("image/x-portable-pixmap" "ppm")
+ ("image/x-rgb" "rgb")
+ ("image/x-xbitmap" "xbm")
+ ("image/x-xpixmap" "xpm")
+ ("image/x-xwindowdump" "xwd")
+ ("model/iges" "igs" "iges")
+ ("model/mesh" "msh" "mesh" "silo")
+ ("model/vrml" "wrl" "vrml")
+ ("text/calendar" "ics" "icz")
+ ("text/comma-separated-values" "csv")
+ ("text/css" "css")
+ ("text/h323" "323")
+ ("text/html" "html" "htm" "shtml")
+ ("text/iuls" "uls")
+ ("text/mathml" "mml")
+ ("text/plain" "asc" "txt" "text" "diff" "pot")
+ ("text/richtext" "rtx")
+ ("text/rtf" "rtf")
+ ("text/scriptlet" "sct" "wsc")
+ ("text/texmacs" "tm" "ts")
+ ("text/tab-separated-values" "tsv")
+ ("text/vnd.sun.j2me.app-descriptor" "jad")
+ ("text/vnd.wap.wml" "wml")
+ ("text/vnd.wap.wmlscript" "wmls")
+ ("text/x-bibtex" "bib")
+ ("text/x-boo" "boo")
+ ("text/x-c++hdr" "h++" "hpp" "hxx" "hh")
+ ("text/x-c++src" "c++" "cpp" "cxx" "cc")
+ ("text/x-chdr" "h")
+ ("text/x-component" "htc")
+ ("text/x-csh" "csh")
+ ("text/x-csrc" "c")
+ ("text/x-dsrc" "d")
+ ("text/x-haskell" "hs")
+ ("text/x-java" "java")
+ ("text/x-literate-haskell" "lhs")
+ ("text/x-moc" "moc")
+ ("text/x-pascal" "pp" "as")
+ ("text/x-pcs-gcd" "gcd")
+ ("text/x-perl" "pl" "pm")
+ ("text/x-python" "py")
+ ("text/x-setext" "etx")
+ ("text/x-sh" "sh")
+ ("text/x-tcl" "tcl" "tk")
+ ("text/x-tex" "tex" "ltx" "sty" "cls")
+ ("text/x-vcalendar" "vcs")
+ ("text/x-vcard" "vcf")
+ ("video/dl" "dl")
+ ("video/dv" "dif" "dv")
+ ("video/fli" "fli")
+ ("video/gl" "gl")
+ ("video/mpeg" "mpeg" "mpg" "mpe")
+ ("video/mp4" "mp4")
+ ("video/quicktime" "qt" "mov")
+ ("video/vnd.mpegurl" "mxu")
+ ("video/x-la-asf" "lsf" "lsx")
+ ("video/x-mng" "mng")
+ ("video/x-ms-asf" "asf" "asx")
+ ("video/x-ms-wm" "wm")
+ ("video/x-ms-wmv" "wmv")
+ ("video/x-ms-wmx" "wmx")
+ ("video/x-ms-wvx" "wvx")
+ ("video/x-msvideo" "avi")
+ ("video/x-sgi-movie" "movie")
+ ("x-conference/x-cooltalk" "ice")
+ ("x-world/x-vrml" "vrm" "vrml" "wrl"))
+ "An alist where the cars are MIME types and the cdrs are list
+of file suffixes for the corresponding type.")
+
+(defparameter *mime-type-hash*
+ (let ((hash (make-hash-table :test #'equalp)))
+ (loop for (type . suffixes) in *mime-type-list* do
+ (loop for suffix in suffixes do
+ (setf (gethash suffix hash) type)))
+ hash)
+ "A hash table which maps file suffixes to MIME types.")
+
+(defun mime-type (pathspec)
+ "Given a pathname designator PATHSPEC returns the MIME type
+\(as a string) corresponding to the suffix of the file denoted by
+PATHSPEC \(or NIL)."
+ (gethash (pathname-type pathspec) *mime-type-hash*))
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/misc.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/misc.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/misc.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,274 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/misc.lisp,v 1.12 2007/11/15 07:29:56 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(let ((scanner-hash (make-hash-table :test #'equal)))
+ (defun scanner-for-get-param (param-name)
+ "Returns a CL-PPCRE scanner which matches a GET parameter in a
+URL. Scanners are memoized in SCANNER-HASH once they are created."
+ (or (gethash param-name scanner-hash)
+ (setf (gethash param-name scanner-hash)
+ (create-scanner
+ `(:alternation
+ ;; session=value at end of URL
+ (:sequence
+ (:char-class #\? #\&)
+ ,param-name
+ #\=
+ (:greedy-repetition 0 nil (:inverted-char-class #\&))
+ :end-anchor)
+ ;; session=value with other parameters following
+ (:sequence
+ (:register (:char-class #\? #\&))
+ ,param-name
+ #\=
+ (:greedy-repetition 0 nil (:inverted-char-class #\&))
+ #\&))))))
+ (defun add-cookie-value-to-url (url &key (cookie-name *session-cookie-name*)
+ (value (session-cookie-value))
+ (replace-ampersands-p t))
+ "Removes all GET parameters named COOKIE-NAME from URL and then
+adds a new GET parameter with the name COOKIE-NAME and the value
+VALUE. If REPLACE-AMPERSANDS-P is true all literal ampersands in URL
+are replaced with '&'. The resulting URL is returned."
+ (unless url
+ ;; see URL-REWRITE:*URL-REWRITE-FILL-TAGS*
+ (setq url (request-uri *request*)))
+ (setq url (regex-replace-all (scanner-for-get-param cookie-name) url "\\1"))
+ (when value
+ (setq url (format nil "~A~:[?~;&~]~A=~A"
+ url
+ (find #\? url)
+ cookie-name
+ (url-encode value))))
+ (when replace-ampersands-p
+ (setq url (regex-replace-all "&" url "&")))
+ url))
+
+(defun maybe-rewrite-urls-for-session (html &key (cookie-name *session-cookie-name*)
+ (value (session-cookie-value)))
+ "Rewrites the HTML page HTML such that the name/value pair
+COOKIE-NAME/COOKIE-VALUE is inserted if the client hasn't sent a
+cookie of the same name but only if *REWRITE-FOR-SESSION-URLS* is
+true. See the docs for URL-REWRITE:REWRITE-URLS."
+ (cond ((or (not *rewrite-for-session-urls*)
+ (null value)
+ (cookie-in cookie-name))
+ html)
+ (t
+ (with-input-from-string (*standard-input* html)
+ (with-output-to-string (*standard-output*)
+ (url-rewrite:rewrite-urls
+ (lambda (url)
+ (add-cookie-value-to-url url
+ :cookie-name cookie-name
+ :value value))))))))
+
+(defmethod dispatch-request (dispatch-table)
+ "Dispatches *REQUEST* based upon rules in the DISPATCH-TABLE.
+This method provides the default Hunchentoot behavior."
+ (loop for dispatcher in dispatch-table
+ for action = (funcall dispatcher *request*)
+ when action return (funcall action)
+ finally (setf (return-code *reply*) +http-not-found+)))
+
+(defun default-dispatcher (request)
+ "Default dispatch function which handles every request with the
+function stored in *DEFAULT-HANDLER*."
+ (declare (ignore request))
+ *default-handler*)
+
+(defun default-handler ()
+ "The handler that is supposed to serve the request if no other
+handler is called."
+ (log-message :info "Default handler called for script ~A" (script-name))
+ (format nil "<html><head><title>Hunchentoot</title></head><body><h2>Hunchentoot Default Page</h2><p>This the Hunchentoot default page. You're most likely seeing it because the server administrator hasn't set up a custom default page yet.</p><p>Hunchentoot is a web server written in <a href='http://www.lisp.org/'>Common Lisp</a>. More info about Hunchentoot can be found at <a href='http://weitz.de/hunchentoot/'>http://weitz.de/hunchentoot/</a>.</p></p><p><hr>~A</p></body></html>"
+ (address-string)))
+
+(defun create-prefix-dispatcher (prefix page-function)
+ "Creates a dispatch function which will dispatch to the
+function denoted by PAGE-FUNCTION if the file name of the current
+request starts with the string PREFIX."
+ (lambda (request)
+ (let ((mismatch (mismatch (script-name request) prefix
+ :test #'char=)))
+ (and (or (null mismatch)
+ (>= mismatch (length prefix)))
+ page-function))))
+
+(defun create-regex-dispatcher (regex page-function)
+ "Creates a dispatch function which will dispatch to the
+function denoted by PAGE-FUNCTION if the file name of the current
+request matches the CL-PPCRE regular expression REGEX."
+ (let ((scanner (create-scanner regex)))
+ (lambda (request)
+ (and (scan scanner (script-name request))
+ page-function))))
+
+(defun handle-static-file (path &optional content-type)
+ "A function which acts like a Hunchentoot handler for the file
+denoted by PATH. Send a content type header corresponding to
+CONTENT-TYPE or \(if that is NIL) tries to determine the content
+type via the file's suffix."
+ (unless (or (pathname-name path)
+ (pathname-type path))
+ ;; not a file
+ (setf (return-code) +http-bad-request+)
+ (throw 'handler-done nil))
+ (unless (probe-file path)
+ ;; does not exist
+ (setf (return-code) +http-not-found+)
+ (throw 'handler-done nil))
+ (let ((time (or (file-write-date path) (get-universal-time))))
+ (setf (content-type) (or content-type
+ (mime-type path)
+ "application/octet-stream"))
+ (handle-if-modified-since time)
+ (with-open-file (file path
+ :direction :input
+ :element-type '(unsigned-byte 8)
+ :if-does-not-exist nil)
+ (setf (header-out "Last-Modified") (rfc-1123-date time)
+ (content-length) (file-length file))
+ (let ((out (send-headers)))
+ (loop with buf = (make-array +buffer-length+ :element-type '(unsigned-byte 8))
+ for pos = (read-sequence buf file)
+ until (zerop pos)
+ do (write-sequence buf out :end pos)
+ (finish-output out))))))
+
+(defun create-static-file-dispatcher-and-handler (uri path &optional content-type)
+ "Creates and returns a dispatch function which will dispatch to a
+handler function which emits the file denoted by the pathname
+designator PATH with content type CONTENT-TYPE if the SCRIPT-NAME of
+the request matches the string URI. If CONTENT-TYPE is NIL tries to
+determine the content type via the file's suffix."
+ ;; the dispatcher
+ (lambda (request)
+ (when (equal (script-name request) uri)
+ ;; the handler
+ (lambda ()
+ (handle-static-file path content-type)))))
+
+(defun enough-url (url url-prefix)
+ "Returns the relative portion of URL relative to URL-PREFIX, similar
+to what ENOUGH-NAMESTRING does for pathnames."
+ (subseq url (mismatch url url-prefix)))
+
+(defun create-folder-dispatcher-and-handler (uri-prefix base-path &optional content-type)
+ "Creates and returns a dispatch function which will dispatch to a
+handler function which emits the file relative to BASE-PATH that is
+denoted by the URI of the request relative to URI-PREFIX. URI-PREFIX
+must be a string ending with a slash, BASE-PATH must be a pathname
+designator for an existing directory. If CONTENT-TYPE is not NIL,
+it'll be the content type used for all files in the folder."
+ (unless (and (stringp uri-prefix)
+ (plusp (length uri-prefix))
+ (char= (char uri-prefix (1- (length uri-prefix))) #\/))
+ (error "~S must be string ending with a slash." uri-prefix))
+ (when (or (pathname-name base-path)
+ (pathname-type base-path))
+ (error "~S is supposed to denote a directory." base-path))
+ (flet ((handler ()
+ (let* ((script-name (url-decode (script-name)))
+ (script-path (enough-url (regex-replace-all "\\\\" script-name "/")
+ uri-prefix))
+ (script-path-directory (pathname-directory script-path)))
+ (unless (or (stringp script-path-directory)
+ (null script-path-directory)
+ (and (listp script-path-directory)
+ (eq (first script-path-directory) :relative)
+ (loop for component in (rest script-path-directory)
+ always (stringp component))))
+ (setf (return-code) +http-forbidden+)
+ (throw 'handler-done nil))
+ (handle-static-file (merge-pathnames script-path base-path) content-type))))
+ (create-prefix-dispatcher uri-prefix #'handler)))
+
+(defun no-cache ()
+ "Adds appropriate headers to completely prevent caching on most browsers."
+ (setf (header-out "Expires")
+ "Mon, 26 Jul 1997 05:00:00 GMT"
+ (header-out "Cache-Control")
+ "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"
+ (header-out "Pragma")
+ "no-cache"
+ (header-out "Last-Modified")
+ (rfc-1123-date))
+ (values))
+
+(defun ssl-p ()
+ "Whether the current connection to the client is secure."
+ (cond ((server-mod-lisp-p *server*) (ssl-session-id *request*))
+ (t #-:hunchentoot-no-ssl (server-ssl-certificate-file *server*)
+ #+:hunchentoot-no-ssl nil)))
+
+(defun redirect (target &key (host (host *request*) host-provided-p)
+ port
+ (protocol (if (ssl-p) :https :http))
+ (add-session-id (not (or host-provided-p
+ (starts-with-scheme-p target)
+ (cookie-in *session-cookie-name*))))
+ permanently)
+ "Redirects the browser to TARGET which should be a string. If
+TARGET is a full URL starting with a scheme, HOST, PORT and PROTOCOL
+are ignored. Otherwise, TARGET should denote the path part of a URL,
+PROTOCOL must be one of the keywords :HTTP or :HTTPS, and the URL to
+redirect to will be constructed from HOST, PORT, PROTOCOL, and TARGET.
+Adds a session ID if ADD-SESSION-ID is true. If PERMANENTLY is true,
+a 301 request is sent to the browser, otherwise a 302."
+ (let ((url (if (starts-with-scheme-p target)
+ target
+ (format nil "~A://~A~@[:~A~]~A"
+ (ecase protocol
+ ((:http) "http")
+ ((:https) "https"))
+ (if port
+ (first (ppcre:split ":" (or host "")))
+ host)
+ port target))))
+ (when add-session-id
+ (setq url (add-cookie-value-to-url url :replace-ampersands-p nil)))
+ (setf (header-out :location)
+ url
+ (return-code *reply*)
+ (if permanently
+ +http-moved-permanently+
+ +http-moved-temporarily+))
+ (throw 'handler-done nil)))
+
+(defun require-authorization (&optional (realm "Hunchentoot"))
+ "Sends back appropriate headers to require basic HTTP authentication
+\(see RFC 2617) for the realm REALM."
+ (setf (header-out "WWW-Authenticate")
+ (format nil "Basic realm=\"~A\"" (quote-string realm))
+ (return-code *reply*)
+ +http-authorization-required+)
+ (throw 'handler-done nil))
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/misc.lisp
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/packages.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/packages.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/packages.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,228 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/packages.lisp,v 1.33 2007/09/18 14:23:23 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :cl-user)
+
+(defpackage :hunchentoot-mp
+ (:nicknames :tbnl-mp)
+ (:use :cl)
+ (:export :*current-process*
+ :make-lock
+ :with-lock
+ :process-run-function
+ :process-kill))
+
+(defpackage :hunchentoot
+ (:nicknames :tbnl)
+ (:use :cl :cl-ppcre :chunga :flexi-streams :url-rewrite :hunchentoot-mp)
+ (:shadow :assoc
+ #+:sbcl :defconstant
+ :handler-case
+ :ignore-errors
+ :url-encode)
+ ;; see ASDF system definition
+ (:import-from :hunchentoot-asd :*hunchentoot-version*)
+ #+:lispworks
+ (:import-from :lw :with-unique-names :when-let)
+ (:export :*approved-return-codes*
+ :*catch-errors-p*
+ :*cleanup-function*
+ :*cleanup-interval*
+ :*content-types-for-url-rewrite*
+ :*default-content-type*
+ :*default-handler*
+ :*default-log-level*
+ :*default-read-timeout*
+ :*default-write-timeout*
+ :*dispatch-table*
+ :*file-upload-hook*
+ :*handle-http-errors-p*
+ :*header-stream*
+ :*http-error-handler*
+ :*hunchentoot-default-external-format*
+ :*lisp-errors-log-level*
+ :*lisp-warnings-log-level*
+ :*listener*
+ :*log-lisp-backtraces-p*
+ :*log-lisp-errors-p*
+ :*log-lisp-warnings-p*
+ :*log-prefix*
+ :*meta-dispatcher*
+ :*methods-for-post-parameters*
+ :*reply*
+ :*request*
+ :*rewrite-for-session-urls*
+ :*server*
+ :*session*
+ :*session-cookie-name*
+ :*session-gc-frequency*
+ :*session-max-time*
+ :*session-removal-hook*
+ :*show-access-log-messages*
+ :*show-lisp-backtraces-p*
+ :*show-lisp-errors-p*
+ :*tmp-directory*
+ :*use-remote-addr-for-sessions*
+ :*use-user-agent-for-sessions*
+ :+http-accepted+
+ :+http-authorization-required+
+ :+http-bad-gateway+
+ :+http-bad-request+
+ :+http-conflict+
+ :+http-continue+
+ :+http-created+
+ :+http-expectation-failed+
+ :+http-failed-dependency+
+ :+http-forbidden+
+ :+http-gateway-time-out+
+ :+http-gone+
+ :+http-internal-server-error+
+ :+http-length-required+
+ :+http-method-not-allowed+
+ :+http-moved-permanently+
+ :+http-moved-temporarily+
+ :+http-multiple-choices+
+ :+http-multi-status+
+ :+http-no-content+
+ :+http-non-authoritative-information+
+ :+http-not-acceptable+
+ :+http-not-found+
+ :+http-not-implemented+
+ :+http-not-modified+
+ :+http-ok+
+ :+http-partial-content+
+ :+http-payment-required+
+ :+http-precondition-failed+
+ :+http-proxy-authentication-required+
+ :+http-request-entity-too-large+
+ :+http-request-time-out+
+ :+http-request-uri-too-large+
+ :+http-requested-range-not-satisfiable+
+ :+http-reset-content+
+ :+http-see-other+
+ :+http-service-unavailable+
+ :+http-switching-protocols+
+ :+http-temporary-redirect+
+ :+http-unsupported-media-type+
+ :+http-use-proxy+
+ :+http-version-not-supported+
+ :authorization
+ :aux-request-value
+ :content-length
+ :content-type
+ :cookie-domain
+ :cookie-expires
+ :cookie-http-only
+ :cookie-in
+ :cookie-name
+ :cookie-out
+ :cookie-path
+ :cookie-secure
+ :cookie-value
+ :cookies-in
+ :cookies-out
+ :create-folder-dispatcher-and-handler
+ :create-prefix-dispatcher
+ :create-regex-dispatcher
+ :create-static-file-dispatcher-and-handler
+ :default-dispatcher
+ :define-easy-handler
+ :delete-aux-request-value
+ :delete-session-value
+ :dispatch-easy-handlers
+ :dispatch-request
+ :do-sessions
+ :escape-for-html
+ :get-backtrace
+ :get-parameter
+ :get-parameters
+ :handle-if-modified-since
+ :handle-static-file
+ :handler-done
+ :header-in
+ :header-out
+ :headers-in
+ :headers-out
+ :host
+ :http-token-p
+ :log-file
+ :log-message
+ :log-message*
+ :maybe-invoke-debugger
+ :mime-type
+ :mod-lisp-id
+ :no-cache
+ :parameter
+ :post-parameter
+ :post-parameters
+ :query-string
+ :raw-post-data
+ :real-remote-addr
+ :reason-phrase
+ :recompute-request-parameters
+ :redirect
+ :referer
+ :remote-addr
+ :remote-port
+ :remove-session
+ :reply-external-format
+ :request-method
+ :request-uri
+ :require-authorization
+ :reset-sessions
+ :return-code
+ :rfc-1123-date
+ :script-name
+ :send-headers
+ :server-addr
+ :server-address
+ :server-dispatch-table
+ :server-local-port
+ :server-name
+ :server-port
+ :server-protocol
+ :session-counter
+ :session-gc
+ :session-max-time
+ :session-too-old-p
+ :session-remote-addr
+ :session-cookie-value
+ :session-user-agent
+ :session-value
+ :set-cookie
+ :set-cookie*
+ :ssl-p
+ :ssl-session-id
+ :start-server
+ :start-session
+ :stop-server
+ :url-decode
+ :url-encode
+ :user-agent))
+
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/packages.lisp
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-acl.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-acl.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-acl.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,145 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/port-acl.lisp,v 1.10 2007/11/03 21:46:18 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ #-(and :allegro-version>= (version>= 7 0))
+ (error "You need at least version 7.0 of AllegroCL.")
+ ;; make sure code for sockets and OS interface is loaded
+ (require :sock)
+ (require :osi))
+
+(defun make-lock (name)
+ "See AllegroCL documentation for MP:MAKE-PROCESS-LOCK."
+ (mp:make-process-lock :name name))
+
+(defmacro with-lock ((lock) &body body)
+ "See AllegroCL documentation for MP:WITH-PROCESS-LOCK."
+ `(mp:with-process-lock (,lock) ,@body))
+
+(defmacro atomic-incf (place &optional (delta 1))
+ "Like INCF but wrapped with SYS:WITHOUT-SCHEDULING so other
+threads can't interfer."
+ `(sys:without-scheduling (incf ,place ,delta)))
+
+(defmacro with-timeout ((seconds &body timeout-forms) &body body)
+ "See AllegroCL documentation for SYS:WITH-TIMEOUT."
+ `(sys:with-timeout (,seconds ,@timeout-forms) ,@body))
+
+(defun process-run-function (name function &rest args)
+ "See AllegroCL documentation for MP:PROCESS-RUN-FUNCTION."
+ (apply #'mp:process-run-function name function args))
+
+(defun process-kill (process)
+ "See AllegroCL documentation for MP:PROCESS-KILL."
+ (mp:process-kill process))
+
+(define-symbol-macro *current-process*
+ mp:*current-process*)
+
+(defun process-allow-scheduling ()
+ "See AllegroCL documentation for MP:PROCESS-ALLOW-SCHEDULE."
+ (mp:process-allow-schedule))
+
+(defun start-up-server (&key service address process-name announce function &allow-other-keys)
+ "Tries to \(partly) emulate LispWorks' COMM:START-UP-SERVER. See
+<http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-56.htm>
+for more info."
+ (let (done)
+ (flet ((open-socket-and-accept ()
+ (handler-bind ((error (lambda (condition)
+ (funcall announce nil condition)
+ (setq done condition)
+ (return-from open-socket-and-accept))))
+ (let (socket)
+ (unwind-protect
+ (progn
+ (setf socket (socket:make-socket :address-family :internet
+ :type :hiper
+ :format :bivalent
+ :connect :passive
+ :local-host address
+ :local-port service
+ :reuse-address t
+ :backlog 5))
+ (funcall announce socket)
+ (setq done socket)
+ (loop (funcall function (socket:accept-connection socket :wait t))))
+ (when socket
+ (cl:ignore-errors (close socket))))))))
+ (let ((listener-thread (process-run-function process-name #'open-socket-and-accept)))
+ (mp:process-wait "Waiting for server to start" (lambda () done))
+ (typecase done
+ (socket:socket listener-thread)
+ (t (values nil done)))))))
+
+(defun make-socket-stream (socket read-timeout write-timeout)
+ "Accepts a socket `handle' SOCKET and creates and returns a
+corresponding stream, setting its read and write timeout if
+applicable. Returns three other values - the address the request
+arrived at, and the address and port of the remote host."
+ ;; in the case of AllegroCL, SOCKET:ACCEPT-CONNECTION already
+ ;; returned a stream
+ (socket:set-socket-options socket :nodelay t)
+ (socket:socket-control socket
+ :read-timeout read-timeout
+ :write-timeout write-timeout)
+ (values socket
+ (ignore-errors
+ (socket:ipaddr-to-dotted (socket:local-host socket)))
+ (ignore-errors
+ (socket:ipaddr-to-dotted (socket:remote-host socket)))
+ (ignore-errors
+ (socket:remote-port socket))))
+
+(defun get-backtrace (error)
+ "This is the function that is used internally by Hunchentoot to
+show or log backtraces. It accepts a condition object ERROR and
+returns a string with the corresponding backtrace."
+ (with-output-to-string (s)
+ (with-standard-io-syntax
+ (let ((*print-readably* nil)
+ (*print-miser-width* 40)
+ (*print-pretty* t)
+ (tpl:*zoom-print-circle* t)
+ (tpl:*zoom-print-level* nil)
+ (tpl:*zoom-print-length* nil))
+ (cl:ignore-errors
+ (format *terminal-io* "~
+~@<An unhandled error condition has been signalled:~3I ~a~I~:@>~%~%"
+ error))
+ (cl:ignore-errors
+ (let ((*terminal-io* s)
+ (*standard-output* s))
+ (tpl:do-command "zoom"
+ :from-read-eval-print-loop nil
+ :count t
+ :all t)))))))
+
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-cmu.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-cmu.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-cmu.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,137 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/port-cmu.lisp,v 1.9 2007/01/01 23:50:30 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+#-:mp
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (error "This library needs a version of CMUCL with MP support."))
+
+(defun make-lock (name)
+ "See CMUCL documentation for MP:MAKE-LOCK."
+ (mp:make-lock name))
+
+(defmacro with-lock ((lock) &body body)
+ "See CMUCL documentation for MP:WITH-LOCK-HELD."
+ `(mp:with-lock-held (,lock) ,@body))
+
+(defmacro atomic-incf (place &optional (delta 1))
+ "Like INCF but wrapped with MP:WITHOUT-SCHEDULING so other
+threads can't interfer."
+ `(mp:without-scheduling (incf ,place ,delta)))
+
+(defmacro with-timeout ((seconds &body timeout-forms) &body body)
+ "See CMUCL documentation for MP:WITH-TIMEOUT."
+ `(mp:with-timeout (,seconds ,@timeout-forms) ,@body))
+
+(defun process-run-function (name function &rest args)
+ "See CMUCL documentation for MP:MAKE-PROCESS."
+ (mp:make-process (lambda ()
+ (apply function args))
+ :name name))
+
+(defun process-kill (process)
+ "See CMUCL documentation for MP:DESTROY-PROCESS."
+ (mp:destroy-process process))
+
+(define-symbol-macro *current-process*
+ mp:*current-process*)
+
+(defun process-allow-scheduling ()
+ "See CMUCL documentation for MP:PROCESS-YIELD."
+ (mp:process-yield))
+
+(defun start-up-server (&key service address process-name announce function &allow-other-keys)
+ "Tries to \(partly) emulate LispWorks' COMM:START-UP-SERVER. See
+<http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-56.htm>
+for more info."
+ (let (done)
+ (flet ((open-socket-and-accept ()
+ (handler-bind ((error (lambda (condition)
+ (funcall announce nil condition)
+ (setq done condition)
+ (return-from open-socket-and-accept))))
+ (let (socket)
+ (unwind-protect
+ (progn
+ (setf socket (ext:create-inet-listener service :stream
+ :reuse-address t
+ :backlog 5
+ :host (or address 0)))
+ (funcall announce socket)
+ (setq done socket)
+ (loop (funcall function (ext:accept-tcp-connection socket))))
+ (when socket
+ (cl:ignore-errors
+ (ext:close-socket socket))))))))
+ (let ((listener-thread (process-run-function process-name #'open-socket-and-accept)))
+ (mp:process-wait "Waiting for server to start" (lambda () done))
+ (typecase done
+ (condition (values nil done))
+ (t listener-thread))))))
+
+(defun format-address (address)
+ "Converts an integer in network byte order denoting an IP
+address into the corresponding string representation."
+ (format nil "~A.~A.~A.~A"
+ (ash address -24)
+ (logand (ash address -16) #xFF)
+ (logand (ash address -8) #xFF)
+ (logand address #xFF)))
+
+(defun make-socket-stream (handle read-timeout write-timeout)
+ "Accepts a socket `handle' HANDLE and creates and returns a
+corresponding stream, setting its read and write timeout if
+applicable. Returns three other values - the address the request
+arrived at, and the address and port of the remote host."
+ (declare (ignore write-timeout))
+ (let ((local-host (ext:get-socket-host-and-port handle)))
+ (multiple-value-bind (remote-host remote-port)
+ (ext:get-peer-host-and-port handle)
+ (values (sys:make-fd-stream handle
+ :input t :output t
+ :element-type '(unsigned-byte 8)
+ :auto-close t
+ :buffering :full
+ :timeout read-timeout
+ :name (format nil "~A:~A" (format-address remote-host) remote-port))
+ (format-address local-host)
+ (format-address remote-host)
+ remote-port))))
+
+(defun get-backtrace (error)
+ "This is the function that is used internally by Hunchentoot to
+show or log backtraces. It accepts a condition object ERROR and
+returns a string with the corresponding backtrace."
+ (declare (ignore error))
+ (with-output-to-string (s)
+ (let ((debug:*debug-print-level* nil)
+ (debug:*debug-print-length* nil))
+ (debug:backtrace most-positive-fixnum s))))
+
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-lw.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-lw.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-lw.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,173 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/port-lw.lisp,v 1.10 2007/11/03 21:46:18 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+#+(and :lispworks4.4 (or :win32 :linux))
+(let ((id :system-cons-free-chain))
+ (unless (scm::patch-id-loaded-p id)
+ (error "You need a patch to improve the performance of this code. Request patch ~S for ~A for ~A from lisp-support(a)lispworks.com using the Report Bug command."
+ id (lisp-implementation-type)
+ #+:win32 "Windows"
+ #+:linux "Linux")))
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ ;; make sure socket code is loaded
+ (require "comm"))
+
+(defun make-lock (name)
+ "See LispWorks documentation for MP:MAKE-LOCK."
+ (mp:make-lock :name name))
+
+(defmacro with-lock ((lock) &body body)
+ "See LispWorks documentation for MP:WITH-LOCK."
+ `(mp:with-lock (,lock) ,@body))
+
+(defmacro atomic-incf (place &optional (delta 1))
+ "Like INCF but wrapped with MP:WITHOUT-PREEMPTION so other
+threads can't interfer."
+ `(mp:without-preemption (incf ,place ,delta)))
+
+(defun invoke-with-timeout (duration body-fn timeout-fn)
+ "Executes the function \(with no arguments) BODY-FN and returns
+its results but stops execution after DURATION seconds and then
+instead calls TIMEOUT-FN and returns its values."
+ ;; from Portable AllegroServe
+ (block timeout
+ (let* ((process mp:*current-process*)
+ (unsheduledp nil)
+ (timer (mp:make-timer
+ #'(lambda ()
+ (mp:process-interrupt process
+ #'(lambda ()
+ (unless unsheduledp
+ (return-from timeout
+ (funcall timeout-fn)))))))))
+ (mp:schedule-timer-relative timer duration)
+ (unwind-protect
+ (funcall body-fn)
+ (mp:without-interrupts
+ (mp:unschedule-timer timer)
+ (setf unsheduledp t))))))
+
+(defmacro with-timeout ((seconds &body timeout-forms) &body body)
+ "Executes the code BODY and returns the results of the last
+form but stops execution after SECONDS seconds and then instead
+executes the code in TIMEOUT-FORMS."
+ ;; from Portable AllegroServe
+ `(invoke-with-timeout ,seconds
+ #'(lambda ()
+ ,@body)
+ #'(lambda ()
+ ,@timeout-forms)))
+
+(defun process-run-function (name function &rest args)
+ "See LispWorks documentation for MP:PROCESS-RUN-FUNCTION."
+ (apply #'mp:process-run-function name nil function args))
+
+(defun process-kill (process)
+ "See LispWorks documentation for MP:PROCESS-KILL."
+ (mp:process-kill process))
+
+(define-symbol-macro *current-process*
+ mp:*current-process*)
+
+(defun process-allow-scheduling ()
+ "See LispWorks documentation for MP:PROCESS-ALLOW-SCHEDULING."
+ (mp:process-allow-scheduling))
+
+(defun start-up-server (&rest args)
+ "See LispWorks documentation for COMM:START-UP-SERVER."
+ (apply #'comm:start-up-server args))
+
+(defun make-socket-stream (socket read-timeout write-timeout)
+ "Accepts a socket `handle' SOCKET and creates and returns a
+corresponding stream, setting its read and write timeout if
+applicable. Returns three other values - the address the request
+arrived at, and the address and port of the remote host."
+ #-:lispworks5.0 (declare (ignore write-timeout))
+ (let ((local-host (comm:get-socket-address socket)))
+ (multiple-value-bind (remote-host remote-port)
+ (comm:get-socket-peer-address socket)
+ (values (make-instance 'comm:socket-stream
+ :socket socket
+ :direction :io
+ :read-timeout read-timeout
+ #+:lispworks5.0 #+:lispworks5.0
+ :write-timeout write-timeout
+ :element-type '(unsigned-byte 8))
+ (ignore-errors
+ (comm:ip-address-string local-host))
+ (ignore-errors
+ (comm:ip-address-string remote-host))
+ remote-port))))
+
+#-:hunchentoot-no-ssl
+(defun make-ssl-server-stream (socket-stream &key certificate-file privatekey-file privatekey-password)
+ "Given the server socket stream SOCKET-STREAM attaches SSL to the
+stream using the certificate file CERTIFICATE-FILE and the private key
+file PRIVATEKEY-FILE. Both of these values must be namestrings
+denoting the location of the files. If PRIVATEKEY-PASSWORD is not NIL
+then it should be the password for the private key file \(if
+necessary)."
+ (flet ((ctx-configure-callback (ctx)
+ (when privatekey-password
+ (comm:set-ssl-ctx-password-callback ctx :password privatekey-password))
+ (comm:ssl-ctx-use-certificate-file ctx
+ certificate-file
+ comm:ssl_filetype_pem)
+ (comm:ssl-ctx-use-privatekey-file ctx
+ privatekey-file
+ comm:ssl_filetype_pem)))
+ (comm:attach-ssl socket-stream
+ :ctx-configure-callback #'ctx-configure-callback)))
+
+(defun get-backtrace (error)
+ "This is the function that is used internally by Hunchentoot to
+show or log backtraces. It accepts a condition object ERROR and
+returns a string with the corresponding backtrace."
+ (declare (ignore error))
+ (with-output-to-string (s)
+ (let ((dbg::*debugger-stack* (dbg::grab-stack nil :how-many most-positive-fixnum))
+ (*debug-io* s)
+ (dbg:*debug-print-level* nil)
+ (dbg:*debug-print-length* nil))
+ (dbg:bug-backtrace nil))))
+
+;; some help for the IDE
+(dspec:define-dspec-alias defvar-unbound (name)
+ `(defparameter ,name))
+
+(dspec:define-dspec-alias def-http-return-code (name)
+ `(defconstant ,name))
+
+(editor:setup-indent "defvar-unbound" 1 2 4)
+
+(editor:setup-indent "def-http-return-code" 1 2 4)
+
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-lw.lisp
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-mcl.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-mcl.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-mcl.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,136 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/port-mcl.lisp,v 1.9 2007/11/03 21:46:19 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(defun make-lock (name)
+ "See OpenMCL documentation for CCL:MAKE-LOCK."
+ (ccl:make-lock name))
+
+(defmacro with-lock ((lock) &body body)
+ "See OpenMCL documentation for CCL:WITH-LOCK-GRABBED."
+ `(ccl:with-lock-grabbed (,lock) ,@body))
+
+(defmacro atomic-incf (place &optional (delta 1))
+ "Like INCF, but other threads can't interfer."
+ `(ccl::atomic-incf-decf ,place ,delta))
+
+(defun invoke-with-timeout (seconds bodyfn timeoutfn)
+ "Executes the function \(with no arguments) BODY-FN and returns
+its results but stops execution after DURATION seconds and then
+instead calls TIMEOUT-FN and returns its values."
+ ;; from Portable AllegroServe
+ (block timeout
+ (let* ((timer (ccl::make-timer-request seconds
+ #'(lambda ()
+ (return-from timeout (funcall timeoutfn))))))
+ (ccl::enqueue-timer-request timer)
+ (unwind-protect (funcall bodyfn)
+ (ccl::dequeue-timer-request timer)))))
+
+(defmacro with-timeout ((seconds &body timeout-forms) &body body)
+ "Executes the code BODY and returns the results of the last
+form but stops execution after SECONDS seconds and then instead
+executes the code in TIMEOUT-FORMS."
+ ;; from Portable AllegroServe
+ `(invoke-with-timeout ,seconds
+ #'(lambda () ,@body)
+ #'(lambda () ,@timeout-forms)))
+
+(defun process-run-function (name function &rest args)
+ "See OpenMCL documentation for CCL:PROCESS-RUN-FUNCTION."
+ (apply #'ccl:process-run-function name function args))
+
+(defun process-kill (process)
+ "See OpenMCL documentation for CCL:PROCESS-KILL."
+ (ccl:process-kill process))
+
+(define-symbol-macro *current-process*
+ ccl:*current-process*)
+
+(defun process-allow-scheduling ()
+ "See OpenMCL documentation for CCL:PROCESS-ALLOW-SCHEDULE"
+ (ccl:process-allow-schedule))
+
+(defun start-up-server (&key service address process-name announce function &allow-other-keys)
+ "Tries to \(partly) emulate LispWorks' COMM:START-UP-SERVER. See
+<http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-56.htm>
+for more info."
+ (let (done)
+ (flet ((open-socket-and-accept ()
+ (handler-bind ((error (lambda (condition)
+ (funcall announce nil condition)
+ (setq done condition)
+ (return-from open-socket-and-accept))))
+ (let (socket)
+ (unwind-protect
+ (progn
+ (setf socket (ccl:make-socket :address-family :internet
+ :type :stream
+ :connect :passive
+ :local-host address
+ :local-port service
+ :reuse-address t
+ :backlog 5))
+ (funcall announce socket)
+ (setq done socket)
+ (loop (funcall function (ccl:accept-connection socket :wait t))))
+ (when socket
+ (cl:ignore-errors
+ (close socket))))))))
+ (let ((listener-thread (process-run-function process-name #'open-socket-and-accept)))
+ (ccl:process-wait "Waiting for server to start" (lambda () done))
+ (typecase done
+ (condition (values nil done))
+ (t listener-thread))))))
+
+(defun make-socket-stream (socket read-timeout write-timeout)
+ "Accepts a socket `handle' SOCKET and creates and returns a
+corresponding stream, setting its read and write timeout if
+applicable. Returns three other values - the address the request
+arrived at, and the address and port of the remote host."
+ (declare (ignore read-timeout write-timeout))
+ (values socket
+ (ignore-errors
+ (ccl:ipaddr-to-dotted (ccl:local-host socket)))
+ (ignore-errors
+ (ccl:ipaddr-to-dotted (ccl:remote-host socket)))
+ (ignore-errors
+ (ccl:remote-port socket))))
+
+(defun get-backtrace (error)
+ "This is the function that is used internally by Hunchentoot to
+show or log backtraces. It accepts a condition object ERROR and
+returns a string with the corresponding backtrace."
+ (with-output-to-string (s)
+ (let ((*debug-io* s))
+ (format *terminal-io* "~
+~@<An unhandled error condition has been signalled:~3I ~a~I~:@>~%~%"
+ error)
+ (ccl:print-call-history :detailed-p nil))))
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-sbcl.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-sbcl.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/port-sbcl.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,205 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/port-sbcl.lisp,v 1.12 2007/09/13 08:35:15 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+#-:sb-unicode
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (error "This library needs a version of SBCL with Unicode support."))
+
+#-:sb-thread
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (warn "Without thread support, this library is only useful for development."))
+
+(defmacro defconstant (name value &optional doc)
+ "Make sure VALUE is evaluated only once \(to appease SBCL)."
+ `(cl:defconstant ,name (if (boundp ',name) (symbol-value ',name) ,value)
+ ,@(when doc (list doc))))
+
+(defun make-lock (name)
+ "See SBCL documentation for SB-THREAD:MAKE-MUTEX."
+ (sb-thread:make-mutex :name name))
+
+(defmacro with-lock ((lock) &body body)
+ "See SBCL documentation for SB-THREAD:WITH-RECURSIVE-LOCK."
+ `(sb-thread:with-recursive-lock (,lock) ,@body))
+
+(defvar *incf-mutex* (sb-thread:make-mutex :name "incf-mutex")
+ "The mutex used for ATOMIC-INCF.")
+
+(defmacro atomic-incf (place &optional (delta 1))
+ "Like INCF but protected by a mutex, so other threads can't
+interfer."
+ `(with-lock (*incf-mutex*) (incf ,place ,delta)))
+
+;; determine whether SB-EXT:WITH-TIMEOUT is supported; we can't just
+;; use (FIND-SYMBOL "WITH-TIMEOUT" "SB-EXT") because sometimes (for
+;; example in SBCL 1.0.6 for Win32) the function is present, but
+;; doesn't work
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (defun ensured-sleep-millis (milliseconds)
+ "Sleeps \(in fact loops) not less then MILLISECONDS number of
+milliseconds; the minimal sleep time is one internal time unit. Don't
+use this function for large time values, because it eats processor
+power."
+ (do ((start-time (get-internal-real-time)))
+ ((< (+ start-time (ceiling (* internal-time-units-per-second
+ (/ milliseconds 1000))))
+ (get-internal-real-time)))))
+ (cl:handler-case
+ (sb-ext:with-timeout 0.0000001 (ensured-sleep-millis 5))
+ (sb-ext:timeout ()
+ (pushnew :hunchentoot-sbcl-with-timeout *features*))
+ (t ())))
+
+(defmacro with-timeout ((seconds &body timeout-forms) &body body)
+ "Executes the code BODY and returns the results of the last
+form but stops execution after SECONDS seconds and then instead
+executes the code in TIMEOUT-FORMS."
+ (declare (ignorable seconds timeout-forms body))
+ #-:hunchentoot-sbcl-with-timeout `(cl:progn ,@body)
+ #+:hunchentoot-sbcl-with-timeout
+ `(cl:handler-case
+ (sb-ext:with-timeout ,seconds ,@body)
+ (sb-ext:timeout () ,@timeout-forms)))
+
+(defun process-run-function (name function &rest args)
+ "See SBCL documentation for SB-THREAD:MAKE-THREAD."
+ (declare (ignorable name))
+ #+:sb-thread
+ (sb-thread:make-thread (lambda ()
+ (apply function args))
+ :name name)
+ #-:sb-thread
+ (apply function args))
+
+(defun process-kill (process)
+ "See SBCL documentation for SB-THREAD:TERMINATE-THREAD."
+ (sb-thread:terminate-thread process))
+
+(define-symbol-macro *current-process*
+ sb-thread:*current-thread*)
+
+(defun process-allow-scheduling ()
+ "Used to simulate a function like PROCESS-ALLOW-SCHEDULING
+which can be found in most other Lisps."
+ (sleep .1))
+
+(defun resolve-hostname (name)
+ "Converts from different types to represent an IP address to
+the canonical representation which is an array with four
+integers."
+ (typecase name
+ (null #(0 0 0 0))
+ (string (car (sb-bsd-sockets:host-ent-addresses
+ (sb-bsd-sockets:get-host-by-name name))))
+ (integer (make-array 4 :initial-contents (list (ash name -24)
+ (logand (ash name -16) #xFF)
+ (logand (ash name -8) #xFF)
+ (logand name #xFF))))
+ (t name)))
+
+(defun start-up-server (&key service address process-name announce function &allow-other-keys)
+ "Tries to \(partly) emulate LispWorks' COMM:START-UP-SERVER. See
+<http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-56.htm>
+for more info."
+ (let (done)
+ (flet ((open-socket-and-accept ()
+ (handler-bind ((error (lambda (condition)
+ (funcall announce nil condition)
+ (setq done condition)
+ (return-from open-socket-and-accept))))
+ (let (socket)
+ (unwind-protect
+ (progn
+ (setf socket (make-instance 'sb-bsd-sockets:inet-socket
+ :type :stream
+ :protocol :tcp)
+ (sb-bsd-sockets:sockopt-reuse-address socket) t)
+ (sb-bsd-sockets:socket-bind socket (resolve-hostname address) service)
+ (sb-bsd-sockets:socket-listen socket 5)
+ (funcall announce socket)
+ (setq done socket)
+ (loop (funcall function (sb-bsd-sockets:socket-accept socket))))
+ (when socket
+ (cl:ignore-errors
+ (sb-bsd-sockets:socket-close socket))))))))
+ (let ((listener-thread (process-run-function process-name #'open-socket-and-accept)))
+ (loop until done do (sleep .1))
+ (typecase done
+ (sb-bsd-sockets:inet-socket listener-thread)
+ (t (values nil done)))))))
+
+(defun format-address (address)
+ "Converts an array of four integers denoting an IP address into
+the corresponding string representation."
+ (format nil "~{~A~^.~}" (coerce address 'list)))
+
+(defun make-socket-stream (socket read-timeout write-timeout)
+ "Accepts a socket `handle' SOCKET and creates and returns a
+corresponding stream, setting its read and write timeout if
+applicable. Returns three other values - the address the request
+arrived at, and the address and port of the remote host."
+ (declare (ignore write-timeout))
+ (let ((local-host (sb-bsd-sockets:socket-name socket)))
+ (multiple-value-bind (remote-host remote-port)
+ (sb-bsd-sockets:socket-peername socket)
+ (values (sb-bsd-sockets:socket-make-stream socket
+ :input t
+ :output t
+ :element-type '(unsigned-byte 8)
+ :timeout read-timeout
+ :buffering :full)
+ (format-address local-host)
+ (format-address remote-host)
+ remote-port))))
+
+;; determine how we're going to access the backtrace in the next
+;; function
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (when (find-symbol "*DEBUG-PRINT-VARIABLE-ALIST*" :sb-debug)
+ (pushnew :hunchentoot-sbcl-debug-print-variable-alist *features*)))
+
+(defun get-backtrace (error)
+ "This is the function that is used internally by Hunchentoot to
+show or log backtraces. It accepts a condition object ERROR and
+returns a string with the corresponding backtrace."
+ (declare (ignore error))
+ (with-output-to-string (s)
+ #+:hunchentoot-sbcl-debug-print-variable-alist
+ (let ((sb-debug:*debug-print-variable-alist*
+ (list* '(*print-level* . nil)
+ '(*print-length* . nil)
+ sb-debug:*debug-print-variable-alist*)))
+ (sb-debug:backtrace most-positive-fixnum s))
+ #-:hunchentoot-sbcl-debug-print-variable-alist
+ (let ((sb-debug:*debug-print-level* nil)
+ (sb-debug:*debug-print-length* nil))
+ (sb-debug:backtrace most-positive-fixnum s))))
+
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/reply.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/reply.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/reply.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,144 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/reply.lisp,v 1.19 2007/09/24 13:43:45 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(defclass reply ()
+ ((content-type :initform *default-content-type*
+ :documentation "The outgoing 'Content-Type' http
+header which defaults to the value of *DEFAULT-CONTENT-TYPE*.")
+ (content-length :initform nil
+ :documentation "The outgoing 'Content-Length'
+http header which defaults NIL. If this is NIL, Hunchentoot will
+compute the content length.")
+ (headers-out :initform nil
+ :documentation "An alist of the outgoing http headers
+not including the 'Set-Cookie', 'Content-Length', and 'Content-Type'
+headers. Use the functions HEADER-OUT and \(SETF HEADER-OUT) to
+modify this slot.")
+ (return-code :initform +http-ok+
+ :documentation "The http return code of this
+reply. The return codes Hunchentoot can handle are defined in
+specials.lisp.")
+ (external-format :initform *hunchentoot-default-external-format*
+ :documentation "The external format of the reply -
+used for character output.")
+ (log-messages :initform nil
+ :reader log-messages
+ :documentation "A list \(in reverse chronological
+order) of the messages which are to be written to the Apache error
+log. This slot's value should only be modified by the functions
+defined in log.lisp.")
+ (cookies-out :initform nil
+ :documentation "The outgoing cookies. This slot's
+value should only be modified by the functions defined in
+cookies.lisp."))
+ (:documentation "Objects of this class hold all the information
+about an outgoing reply. They are created automatically by
+Hunchentoot and can be accessed and modified by the corresponding
+handler."))
+
+(defun headers-out (&optional (reply *reply*))
+ "Returns an alist of the outgoing headers associated with the
+REPLY object REPLY."
+ (slot-value reply 'headers-out))
+
+(defun cookies-out (&optional (reply *reply*))
+ "Returns an alist of the outgoing cookies associated with the
+REPLY object REPLY."
+ (slot-value reply 'cookies-out))
+
+(defun (setf cookies-out) (new-value &optional (reply *reply*))
+ "Returns an alist of the outgoing cookies associated with the
+REPLY object REPLY."
+ (setf (slot-value reply 'cookies-out) new-value))
+
+(defun content-type (&optional (reply *reply*))
+ "The outgoing 'Content-Type' http header of REPLY."
+ (slot-value reply 'content-type))
+
+(defun (setf content-type) (new-value &optional (reply *reply*))
+ "Sets the outgoing 'Content-Type' http header of REPLY."
+ (setf (slot-value reply 'content-type) new-value))
+
+(defun content-length (&optional (reply *reply*))
+ "The outgoing 'Content-Length' http header of REPLY."
+ (slot-value reply 'content-length))
+
+(defun (setf content-length) (new-value &optional (reply *reply*))
+ "Sets the outgoing 'Content-Length' http header of REPLY."
+ (setf (slot-value reply 'content-length) new-value))
+
+(defun return-code (&optional (reply *reply*))
+ "The http return code of REPLY. The return codes Hunchentoot can
+handle are defined in specials.lisp."
+ (slot-value reply 'return-code))
+
+(defun (setf return-code) (new-value &optional (reply *reply*))
+ "Sets the http return code of REPLY."
+ (setf (slot-value reply 'return-code) new-value))
+
+(defun reply-external-format (&optional (reply *reply*))
+ "The external format of REPLY which is used for character output."
+ (slot-value reply 'external-format))
+
+(defun (setf reply-external-format) (new-value &optional (reply *reply*))
+ "Sets the external format of REPLY."
+ (setf (slot-value reply 'external-format) new-value))
+
+(defun header-out-set-p (name &optional (reply *reply*))
+ "Returns a true value if the outgoing http header named NAME has
+been specified already. NAME should be a keyword or a string."
+ (assoc name (headers-out reply)))
+
+(defun header-out (name &optional (reply *reply*))
+ "Returns the current value of the outgoing http header named NAME.
+NAME should be a keyword or a string."
+ (cdr (assoc name (headers-out reply))))
+
+(defun cookie-out (name &optional (reply *reply*))
+ "Returns the current value of the outgoing cookie named
+NAME. Search is case-sensitive."
+ (cdr (assoc name (cookies-out reply) :test #'string=)))
+
+(defsetf header-out (name &optional (reply '*reply*))
+ (new-value)
+ "Changes the current value of the outgoing http header named NAME (a
+keyword or a string). If a header with this name doesn't exist, it is
+created."
+ (with-rebinding (name reply)
+ (with-unique-names (symbol place)
+ `(let* ((,symbol (if (stringp ,name) (make-keyword ,name :destructivep nil) ,name))
+ (,place (assoc ,symbol (headers-out ,reply) :test #'string-equal)))
+ (cond
+ (,place
+ (setf (cdr ,place) ,new-value))
+ (t
+ (push (cons ,symbol ,new-value) (slot-value ,reply 'headers-out))
+ ,new-value))))))
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/request.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/request.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/request.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,474 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/request.lisp,v 1.33 2007/09/14 12:12:33 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(defclass request ()
+ ((headers-in :initarg :headers-in
+ :documentation "An alist of the incoming headers. Note
+that these might be the headers coming in from mod_lisp which are
+different from the headers sent by the client.")
+ (method :initarg :method
+ :documentation "The request method as a keyword. This slot
+is only filled if we're not behind mod_lisp.")
+ (uri :initarg :uri
+ :documentation "The request URI as a string. This slot is
+only filled if we're not behind mod_lisp.")
+ (server-protocol :initarg :server-protocol
+ :documentation "The HTTP protocol as a keyword.
+This slot is only filled if we're not behind mod_lisp.")
+ (content-stream :initarg :content-stream
+ :reader content-stream
+ :documentation "A stream from which the request
+body can be read if there is one.")
+ (cookies-in :initform nil
+ :documentation "An alist of the cookies sent by the client.")
+ (get-parameters :initform nil
+ :documentation "An alist of the GET parameters sent
+by the client.")
+ (post-parameters :initform nil
+ :documentation "An alist of the POST parameters
+sent by the client.")
+ (script-name :initform nil
+ :documentation "The URI requested by the client without
+the query string.")
+ (query-string :initform nil
+ :documentation "The query string of this request.")
+ (session :initform nil
+ :accessor session
+ :documentation "The session object associated with this
+request.")
+ (aux-data :initform nil
+ :accessor aux-data
+ :documentation "Used to keep a user-modifiable alist with
+arbitrary data during the request.")
+ (raw-post-data :initform nil
+ :documentation "The raw string sent as the body of a
+POST request, populated only if not a multipart/form-data request."))
+ (:documentation "Objects of this class hold all the information
+about an incoming request. They are created automatically by
+Hunchentoot and can be accessed by the corresponding handler."))
+
+(defun parse-rfc2388-form-data (stream content-type-header)
+ "Creates an alist of POST parameters from the stream STREAM which is
+supposed to be of content type 'multipart/form-data'."
+ (let* ((parsed-content-type-header (rfc2388:parse-header content-type-header :value))
+ (boundary (or (cdr (rfc2388:find-parameter
+ "BOUNDARY"
+ (rfc2388:header-parameters parsed-content-type-header)))
+ (return-from parse-rfc2388-form-data))))
+ (loop for part in (rfc2388:parse-mime stream boundary)
+ for headers = (rfc2388:mime-part-headers part)
+ for content-disposition-header = (rfc2388:find-content-disposition-header headers)
+ for name = (cdr (rfc2388:find-parameter
+ "NAME"
+ (rfc2388:header-parameters content-disposition-header)))
+ when name
+ collect (cons name
+ (let ((contents (rfc2388:mime-part-contents part)))
+ (if (pathnamep contents)
+ (list contents
+ (rfc2388:get-file-name headers)
+ (rfc2388:content-type part :as-string t))
+ contents))))))
+
+(defun get-post-data (&key (request *request*) want-stream (already-read 0))
+ "Reads the request body from the stream and stores the raw contents
+\(as an array of octets) in the corresponding slot of the REQUEST
+object. Returns just the stream if WANT-STREAM is true. If there's a
+Content-Length header, it is assumed, that ALREADY-READ octets have
+already been read."
+ (let* ((headers-in (headers-in request))
+ (content-length (when-let (content-length-header (cdr (assoc :content-length headers-in)))
+ (parse-integer content-length-header :junk-allowed t)))
+ (content-stream (content-stream request)))
+ (setf (slot-value request 'raw-post-data)
+ (cond (want-stream
+ (setf (flexi-stream-position *hunchentoot-stream*) 0)
+ (when content-length
+ (setf (flexi-stream-bound content-stream) content-length))
+ content-stream)
+ ((and content-length (> content-length already-read))
+ (decf content-length already-read)
+ (when (input-chunking-p)
+ ;; see RFC 2616, section 4.4
+ (log-message :warn "Got Content-Length header although input chunking is on."))
+ (let ((content (make-array content-length :element-type 'octet)))
+ (read-sequence content content-stream)
+ content))
+ ((input-chunking-p)
+ (loop with buffer = (make-array +buffer-length+ :element-type 'octet)
+ with content = (make-array 0 :element-type 'octet :adjustable t)
+ for index = 0 then (+ index pos)
+ for pos = (read-sequence buffer content-stream)
+ do (adjust-array content (+ index pos))
+ (replace content buffer :start1 index :end2 pos)
+ while (= pos +buffer-length+)
+ finally (return content)))))))
+
+(defmethod initialize-instance :after ((request request) &rest init-args)
+ "The only initarg for a REQUEST object is :HEADERS-IN. All other
+slot values are computed in this :AFTER method."
+ (declare (ignore init-args))
+ (with-slots (headers-in cookies-in get-parameters post-parameters script-name query-string session)
+ request
+ (handler-case
+ (progn
+ (when (server-mod-lisp-p *server*)
+ ;; convert these two values to keywords
+ (let ((method-pair (assoc :method headers-in)))
+ (setf (cdr method-pair) (make-keyword (cdr method-pair))))
+ (let ((protocol-pair (assoc :server-protocol headers-in)))
+ (setf (cdr protocol-pair) (make-keyword (cdr protocol-pair))))
+ ;; and convert these two values to integers
+ (let ((remote-ip-port-pair (assoc :remote-ip-port headers-in)))
+ (setf (cdr remote-ip-port-pair) (parse-integer (cdr remote-ip-port-pair)
+ :junk-allowed t)))
+ (let ((server-ip-port-pair (assoc :server-ip-port headers-in)))
+ (setf (cdr server-ip-port-pair) (parse-integer (cdr server-ip-port-pair)
+ :junk-allowed t))))
+ ;; compute SCRIPT-NAME and QUERY-STRING slots from
+ ;; REQUEST_URI environment variable
+ (let* ((uri (request-uri request))
+ (match-start (position #\? uri)))
+ (cond
+ (match-start
+ (setq script-name (subseq uri 0 match-start)
+ query-string (subseq uri (1+ match-start))))
+ (t (setq script-name uri))))
+ ;; some clients (e.g. ASDF-INSTALL) send requests like
+ ;; "GET http://server/foo.html HTTP/1.0"...
+ (setq script-name (regex-replace "^https?://[^/]+" script-name ""))
+ ;; compute GET parameters from query string and cookies from
+ ;; the incoming 'Cookie' header
+ (setq get-parameters
+ (form-url-encoded-list-to-alist (split "&" query-string))
+ cookies-in
+ (form-url-encoded-list-to-alist (split "\\s*[,;]\\s*" (cdr (assoc :cookie headers-in)))
+ +utf-8+)
+ session (session-verify request)
+ *session* session)
+ ;; if the content-type is 'application/x-www-form-urlencoded'
+ ;; or 'multipart/form-data', compute the post parameters from
+ ;; the content body
+ (when (member (request-method request) *methods-for-post-parameters* :test #'eq)
+ (when-let (content-type (cdr (assoc :content-type headers-in)))
+ (multiple-value-bind (type subtype external-format)
+ (parse-content-type content-type t)
+ (setq post-parameters
+ (cond ((and (string-equal type "application")
+ (string-equal subtype "x-www-form-urlencoded"))
+ (unless (or (assoc :content-length headers-in)
+ (input-chunking-p))
+ (error "Can't read request body because there's no~
+Content-Length header and input chunking is off."))
+ (form-url-encoded-list-to-alist
+ (split "&" (raw-post-data :request request
+ ;; ASCII would suffice according to RFC...
+ :external-format +latin-1+))
+ external-format))
+ ((and (string-equal type "multipart")
+ (string-equal subtype "form-data"))
+ (setf (slot-value request 'raw-post-data) t)
+ (handler-case
+ (let* ((*request* request)
+ (content-stream (content-stream request))
+ (start (flexi-stream-position content-stream)))
+ (prog1
+ (parse-rfc2388-form-data content-stream content-type)
+ (let* ((end (flexi-stream-position content-stream))
+ (stray-data (get-post-data :already-read (- end start))))
+ (when (and stray-data (plusp (length stray-data)))
+ (warn "~A octets of stray data after form-data sent by client."
+ (length stray-data))))
+ (setf (slot-value request 'raw-post-data) t)))
+ (error (msg)
+ (log-message :error
+ "While parsing multipart/form-data parameters: ~A"
+ msg)
+ nil)))))))))
+ (error (cond)
+ (log-message* "Error when creating REQUEST object: ~A" cond)
+ ;; we assume it's not our fault...
+ (setf (return-code) +http-bad-request+)))))
+
+(defun recompute-request-parameters (&key (request *request*)
+ (external-format *hunchentoot-default-external-format*))
+ "Recomputes the GET and POST parameters for the REQUEST object
+REQUEST. This only makes sense if you're switching external formats
+during the request."
+ (with-slots (headers-in get-parameters post-parameters query-string)
+ request
+ (setq get-parameters
+ (form-url-encoded-list-to-alist (split "&" query-string) external-format)
+ post-parameters
+ (when-let (raw-post-data (raw-post-data :request request
+ :external-format +latin-1+))
+ (and (when-let (content-type (cdr (assoc :content-type headers-in)))
+ (multiple-value-bind (type subtype)
+ (parse-content-type content-type)
+ (and (string-equal type "application")
+ (string-equal subtype "x-www-form-urlencoded"))))
+ (form-url-encoded-list-to-alist (split "&" raw-post-data) external-format)))))
+ (values))
+
+(defun script-name (&optional (request *request*))
+ "Returns the file name of the REQUEST object REQUEST. That's the
+requested URI without the query string \(i.e the GET parameters)."
+ (slot-value request 'script-name))
+
+(defun query-string (&optional (request *request*))
+ "Returns the query string of the REQUEST object REQUEST. That's
+the part behind the question mark \(i.e. the GET parameters)."
+ (slot-value request 'query-string))
+
+(defun get-parameters (&optional (request *request*))
+ "Returns an alist of the GET parameters associated with the REQUEST
+object REQUEST."
+ (slot-value request 'get-parameters))
+
+(defun post-parameters (&optional (request *request*))
+ "Returns an alist of the POST parameters associated with the REQUEST
+object REQUEST."
+ (slot-value request 'post-parameters))
+
+(defun headers-in (&optional (request *request*))
+ "Returns an alist of the incoming headers associated with the
+REQUEST object REQUEST."
+ (slot-value request 'headers-in))
+
+(defun cookies-in (&optional (request *request*))
+ "Returns an alist of all cookies associated with the REQUEST object
+REQUEST."
+ (slot-value request 'cookies-in))
+
+(defun header-in (name &optional (request *request*))
+ "Returns the incoming header with name NAME. NAME can be a keyword
+\(recommended) or a string."
+ (cdr (assoc name (headers-in request))))
+
+(defun authorization (&optional (request *request*))
+ "Returns as two values the user and password \(if any) as encoded in
+the 'AUTHORIZATION' header. Returns NIL if there is no such header."
+ (let* ((authorization (header-in :authorization request))
+ (start (and authorization
+ (> (length authorization) 5)
+ (string-equal "Basic" authorization :end2 5)
+ (scan "\\S" authorization :start 5))))
+ (when start
+ (destructuring-bind (&optional user password)
+ (split ":" (base64:base64-string-to-string (subseq authorization start)))
+ (values user password)))))
+
+(defun remote-addr (&optional (request *request*))
+ "Returns the address the current request originated from."
+ (cond ((server-mod-lisp-p *server*) (header-in :remote-ip-addr request))
+ (t *remote-host*)))
+
+(defun real-remote-addr (&optional (request *request*))
+ "Returns the 'X-Forwarded-For' incoming http header as the
+second value in the form of a list of IP addresses and the first
+element of this list as the first value if this header exists.
+Otherwise returns the value of REMOTE-ADDR as the only value."
+ (let ((x-forwarded-for (header-in :x-forwarded-for request)))
+ (cond (x-forwarded-for (let ((addresses (split "\\s*,\\s*" x-forwarded-for)))
+ (values (first addresses) addresses)))
+ (t (remote-addr request)))))
+
+(defun server-addr (&optional (request *request*))
+ "Returns the address at which the current request arrived."
+ (cond ((server-mod-lisp-p *server*) (header-in :server-ip-addr request))
+ (t *local-host*)))
+
+(defun remote-port (&optional (request *request*))
+ "Returns the port the current request originated from."
+ (cond ((server-mod-lisp-p *server*) (header-in :remote-ip-port request))
+ (t *remote-port*)))
+
+(defun server-port (&optional (request *request*))
+ "Returns the port at which the current request arrived."
+ (cond ((server-mod-lisp-p *server*) (header-in :server-ip-port request))
+ (t (server-local-port *server*))))
+
+(defun host (&optional (request *request*))
+ "Returns the 'Host' incoming http header value."
+ (header-in :host request))
+
+(defun request-uri (&optional (request *request*))
+ "Returns the request URI."
+ (cond ((server-mod-lisp-p *server*) (header-in :url request))
+ (t (slot-value request 'uri))))
+
+(defun request-method (&optional (request *request*))
+ "Returns the request method as a Lisp keyword."
+ (cond ((server-mod-lisp-p *server*) (header-in :method request))
+ (t (slot-value request 'method))))
+
+(defun server-protocol (&optional (request *request*))
+ "Returns the request protocol as a Lisp keyword."
+ (cond ((server-mod-lisp-p *server*) (header-in :server-protocol request))
+ (t (slot-value request 'server-protocol))))
+
+(defun mod-lisp-id (&optional (request *request*))
+ "Returns the 'Server ID' sent by mod_lisp. This value is set in
+Apache's server configuration file and is of course only available if
+mod_lisp is the front-end."
+ (and (or (server-mod-lisp-p *server*)
+ (warn "Calling MOD-LISP-ID although ~S is a stand-alone server."
+ *server*))
+ (header-in :server-id request)))
+
+(defun ssl-session-id (&optional (request *request*))
+ "Returns the 'SSL_SESSION_ID' header sent my mod_lisp and is of
+course only available if mod_lisp is the front-end."
+ (and (or (server-mod-lisp-p *server*)
+ (warn "Calling SSL-SESSION-ID although ~S is a stand-alone server."
+ *server*))
+ (header-in :ssl-session-id request)))
+
+(defun user-agent (&optional (request *request*))
+ "Returns the 'User-Agent' http header."
+ (header-in :user-agent request))
+
+(defun cookie-in (name &optional (request *request*))
+ "Returns the cookie with the name NAME \(a string) as sent by the
+browser - or NIL if there is none."
+ (cdr (assoc name (cookies-in request) :test #'string=)))
+
+(defun referer (&optional (request *request*))
+ "Returns the 'Referer' \(sic!) http header."
+ (header-in :referer request))
+
+(defun get-parameter (name &optional (request *request*))
+ "Returns the GET parameter with name NAME \(a string) - or NIL if
+there is none. Search is case-sensitive."
+ (cdr (assoc name (get-parameters request) :test #'string=)))
+
+(defun post-parameter (name &optional (request *request*))
+ "Returns the POST parameter with name NAME \(a string) - or NIL if
+there is none. Search is case-sensitive."
+ (cdr (assoc name (post-parameters request) :test #'string=)))
+
+(defun parameter (name &optional (request *request*))
+ "Returns the GET or the POST parameter with name NAME \(a string) -
+or NIL if there is none. If both a GET and a POST parameter with the
+same name exist the GET parameter is returned. Search is
+case-sensitive."
+ (or (get-parameter name request)
+ (post-parameter name request)))
+
+(defun handle-if-modified-since (time &optional (request *request*))
+ "Handles the 'If-Modified-Since' header of REQUEST. The date string
+is compared to the one generated from the supplied universal time
+TIME."
+ (let ((if-modified-since (header-in :if-modified-since request))
+ (time-string (rfc-1123-date time)))
+ ;; simple string comparison is sufficient; see RFC 2616 14.25
+ (when (and if-modified-since
+ (equal if-modified-since time-string))
+ (setf (return-code) +http-not-modified+)
+ (throw 'handler-done nil))
+ (values)))
+
+(defun raw-post-data (&key (request *request*) external-format force-binary force-text want-stream)
+ "Returns the content sent by the client if there was any \(unless
+the content type was \"multipart/form-data\"). By default, the result
+is a string if the type of the `Content-Type' media type is \"text\",
+and a vector of octets otherwise. In the case of a string, the
+external format to be used to decode the content will be determined
+from the `charset' parameter sent by the client \(or otherwise
+*HUNCHENTOOT-DEFAULT-EXTERNAL-FORMAT* will be used).
+
+You can also provide an external format explicitly \(through
+EXTERNAL-FORMAT) in which case the result will unconditionally be a
+string. Likewise, you can provide a true value for FORCE-TEXT which
+will force Hunchentoot to act as if the type of the media type had
+been \"text\". Or you can provide a true value for FORCE-BINARY which
+means that you want a vector of octets at any rate.
+
+If, however, you provide a true value for WANT-STREAM, the other
+parameters are ignored and you'll get the content \(flexi) stream to
+read from it yourself. It is then your responsibility to read the
+correct amount of data, because otherwise you won't be able to return
+a response to the client. If the content type of the request was
+`multipart/form-data' or `application/x-www-form-urlencoded', the
+content has been read by Hunchentoot already and you can't read from
+the stream anymore.
+
+You can call RAW-POST-DATA more than once per request, but you can't
+mix calls which have different values for WANT-STREAM.
+
+Note that this function is slightly misnamed because a client can send
+content even if the request method is not POST."
+ (when (and force-binary force-text)
+ (error "It doesn't make sense to set both FORCE-BINARY and FORCE-TEXT to a true value."))
+ (unless (or external-format force-binary)
+ (setq external-format
+ (when-let (content-type (cdr (assoc :content-type (headers-in request))))
+ (nth-value 2 (parse-content-type content-type force-text)))))
+ (let ((raw-post-data (or (slot-value request 'raw-post-data)
+ (get-post-data :request request :want-stream want-stream))))
+ (cond ((typep raw-post-data 'stream) raw-post-data)
+ ((member raw-post-data '(t nil)) nil)
+ (external-format (octets-to-string raw-post-data :external-format external-format))
+ (t raw-post-data))))
+
+(defun aux-request-value (symbol &optional (request *request*))
+ "Returns the value associated with SYMBOL from the request object
+REQUEST \(the default is the current request) if it exists. The
+second return value is true if such a value was found."
+ (when request
+ (let ((found (assoc symbol (aux-data request))))
+ (values (cdr found) found))))
+
+(defsetf aux-request-value (symbol &optional request)
+ (new-value)
+ "Sets the value associated with SYMBOL from the request object
+REQUEST \(default is *REQUEST*). If there is already a value
+associated with SYMBOL it will be replaced."
+ (with-rebinding (symbol)
+ (with-unique-names (place %request)
+ `(let* ((,%request (or ,request *request*))
+ (,place (assoc ,symbol (aux-data ,%request))))
+ (cond
+ (,place
+ (setf (cdr ,place) ,new-value))
+ (t
+ (push (cons ,symbol ,new-value)
+ (aux-data ,%request))
+ ,new-value))))))
+
+(defun delete-aux-request-value (symbol &optional (request *request*))
+ "Removes the value associated with SYMBOL from the request object
+REQUEST."
+ (when request
+ (setf (aux-data request)
+ (delete symbol (aux-data request)
+ :key #'car :test #'eq)))
+ (values))
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/server.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/server.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/server.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,440 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/server.lisp,v 1.38 2007/11/03 21:46:19 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(defclass server ()
+ ((socket :accessor server-socket
+ :documentation "The socket the server is listening on.")
+ (port :initarg :port
+ :reader server-local-port
+ :documentation "The port the server is listening on.
+See START-SERVER.")
+ (address :initarg :address
+ :reader server-address
+ :documentation "The address the server is listening
+on. See START-SERVER.")
+ (name :initarg :name
+ :accessor server-name
+ :documentation "The optional name of the server, a symbol.")
+ (dispatch-table :initarg :dispatch-table
+ :accessor server-dispatch-table
+ :documentation "The dispatch-table used by this
+server. Can be NIL to denote that *META-DISPATCHER* should be called
+instead.")
+ (output-chunking-p :initarg :output-chunking-p
+ :reader server-output-chunking-p
+ :documentation "Whether the server may use output chunking.")
+ (input-chunking-p :initarg :input-chunking-p
+ :reader server-input-chunking-p
+ :documentation "Whether the server may use input chunking.")
+ (read-timeout :initarg :read-timeout
+ :reader server-read-timeout
+ :documentation "The read-timeout of the server.")
+ (write-timeout :initarg :write-timeout
+ :reader server-write-timeout
+ :documentation "The write-timeout of the server.")
+ (listener :accessor server-listener
+ :documentation "The Lisp process which listens for
+incoming requests and starts new worker threads for each new
+connection.")
+ (workers :initform nil
+ :accessor server-workers
+ :documentation "A list of currently active worker threads.")
+ (mod-lisp-p :initform nil
+ :initarg :mod-lisp-p
+ :reader server-mod-lisp-p
+ :documentation "Whether this is a genuine
+Hunchentoot server or \"just\" infrastructure for mod_lisp.")
+ (use-apache-log-p :initarg :use-apache-log-p
+ :reader server-use-apache-log-p
+ :documentation "Whether the server should use
+Apache's log file. Only applicable if MOD-LISP-P is true.")
+ #-:hunchentoot-no-ssl
+ (ssl-certificate-file :initarg :ssl-certificate-file
+ :reader server-ssl-certificate-file
+ :documentation "The namestring of a
+certificate file if SSL is used, NIL otherwise.")
+ #-:hunchentoot-no-ssl
+ (ssl-privatekey-file :initarg :ssl-privatekey-file
+ :reader server-ssl-privatekey-file
+ :documentation "The namestring of a
+private key file if SSL is used, NIL otherwise.")
+ #-:hunchentoot-no-ssl
+ (ssl-privatekey-password :initarg :ssl-privatekey-password
+ :reader server-ssl-privatekey-password
+ :documentation "The password for the
+private key file or NIL.")
+ (lock :initform (make-lock (format nil "hunchentoot-lock-~A"
+ *server-counter*))
+ :reader server-lock
+ :documentation "A lock which is used to make sure that
+we can shutdown the server cleanly."))
+ (:documentation "An object of this class contains all relevant
+information about a running Hunchentoot server instance."))
+
+(defun start-server (&key (port 80 port-provided-p)
+ address
+ dispatch-table
+ (name (gensym))
+ (mod-lisp-p nil)
+ (use-apache-log-p mod-lisp-p)
+ (input-chunking-p t)
+ (read-timeout *default-read-timeout*)
+ (write-timeout *default-write-timeout*)
+ #+(and :unix (not :win32)) setuid
+ #+(and :unix (not :win32)) setgid
+ #-:hunchentoot-no-ssl ssl-certificate-file
+ #-:hunchentoot-no-ssl (ssl-privatekey-file ssl-certificate-file)
+ #-:hunchentoot-no-ssl ssl-privatekey-password)
+ "Starts a Hunchentoot server and returns the SERVER object \(which
+can be stopped with STOP-SERVER). PORT is the port the server will be
+listening on - the default is 80 \(or 443 if SSL information is
+provided). If ADDRESS is a string denoting an IP address, then the
+server only receives connections for that address. This must be one
+of the addresses associated with the machine and allowed values are
+host names such as \"www.nowhere.com\" and address strings like
+\"204.71.177.75\". If ADDRESS is NIL, then the server will receive
+connections to all IP addresses on the machine. This is the default.
+
+DISPATCH-TABLE can either be a dispatch table which is to be used by
+this server or NIL which means that at request time *META-DISPATCHER*
+will be called to retrieve a dispatch table.
+
+NAME should be a symbol which can be used to name the server. This
+name can utilized when defining \"easy handlers\" - see
+DEFINE-EASY-HANDLER. The default name is an uninterned symbol as
+returned by GENSYM.
+
+If MOD-LISP-P is true, the server will act as a back-end for mod_lisp,
+otherwise it will be a stand-alone web server. If USE-APACHE-LOG-P is
+true, log messages will be written to the Apache log file - this
+parameter has no effect if MOD-LISP-P is NIL.
+
+If INPUT-CHUNKING-P is true, the server will accept request bodies
+without a `Content-Length' header if the client uses chunked transfer
+encoding. If you want to use this feature together with mod_lisp, you
+should make sure that your combination of Apache and mod_lisp can do
+that - see:
+
+ <http://common-lisp.net/pipermail/mod-lisp-devel/2006-December/000104.html>.
+
+On LispWorks 5.0 or higher and AllegroCL, READ-TIMEOUT and
+WRITE-TIMEOUT are the read and write timeouts \(in seconds) of
+the server - use NIL for no timeout at all. (See the LispWorks
+documentation for STREAM:SOCKET-STREAM for details.) On
+LispWorks 4.4.6 or lower, SBCL, and CMUCL WRITE-TIMEOUT is
+ignored. On OpenMCL both parameters are ignored.
+
+On Unix you can use SETUID and SETGID to change the UID and GID of the
+process directly after the server has been started. \(You might want
+to do this if you're using a privileged port like 80.) SETUID and
+SETGID can be integers \(the actual IDs) or strings \(for the user and
+group name respectively).
+
+If you want your server to use SSL you must provide the pathname
+designator\(s) SSL-CERTIFICATE-FILE for the certificate file and
+optionally SSL-PRIVATEKEY-FILE for the private key file, both files
+must be in PEM format. If you only provide the value for
+SSL-CERTIFICATE-FILE it is assumed that both the certificate and the
+private key are in one file. If your private key needs a password you
+can provide it through the SSL-PRIVATEKEY-PASSWORD keyword argument,
+but this works only on LispWorks - for other Lisps the key must not be
+associated with a password."
+ (declare (ignorable port-provided-p))
+ ;; initialize the session secret if needed
+ (unless (boundp '*session-secret*)
+ (reset-session-secret))
+ (let ((output-chunking-p t))
+ #-:hunchentoot-no-ssl
+ (when ssl-certificate-file
+ ;; disable output chunking for SSL connections
+ (setq output-chunking-p nil)
+ (unless port-provided-p (setq port 443)))
+ ;; no timeouts if behind mod_lisp
+ (when mod-lisp-p
+ (setq read-timeout nil
+ write-timeout nil))
+ ;; use a new process/lock name for each server
+ (atomic-incf *server-counter*)
+ ;; create the SERVER object
+ (let ((server (make-instance 'server
+ :port port
+ :address address
+ :name name
+ :dispatch-table dispatch-table
+ :output-chunking-p (and output-chunking-p (not mod-lisp-p))
+ :input-chunking-p input-chunking-p
+ #-:hunchentoot-no-ssl :ssl-certificate-file
+ #-:hunchentoot-no-ssl(and ssl-certificate-file
+ (namestring ssl-certificate-file))
+ #-:hunchentoot-no-ssl :ssl-privatekey-file
+ #-:hunchentoot-no-ssl (and ssl-privatekey-file
+ (namestring ssl-privatekey-file))
+ #-:hunchentoot-no-ssl :ssl-privatekey-password
+ #-:hunchentoot-no-ssl ssl-privatekey-password
+ :mod-lisp-p mod-lisp-p
+ :use-apache-log-p (and mod-lisp-p use-apache-log-p)
+ :read-timeout read-timeout
+ :write-timeout write-timeout)))
+ (multiple-value-bind (process condition)
+ ;; start up the actual server
+ (start-up-server :service port
+ :address address
+ :process-name (format nil "hunchentoot-listener-~A" *server-counter*)
+ ;; this function is called once on
+ ;; startup - we use it to record the
+ ;; socket
+ :announce (lambda (socket &optional condition)
+ (cond (socket
+ (setf (server-socket server) socket))
+ (condition
+ (error condition))))
+ ;; this function is called whenever a
+ ;; connection is made
+ :function (lambda (handle)
+ (with-lock ((server-lock server))
+ (incf *worker-counter*)
+ ;; check if we need to
+ ;; perform a global GC
+ (when (and *cleanup-interval*
+ (zerop (mod *worker-counter* *cleanup-interval*)))
+ (when *cleanup-function*
+ (funcall *cleanup-function*)))
+ ;; start a worker thread
+ ;; for this connection
+ ;; and remember it
+ (push (process-run-function (format nil "hunchentoot-worker-~A"
+ *worker-counter*)
+ #'process-connection
+ server handle)
+ (server-workers server))))
+ ;; wait until the server was
+ ;; successfully started or an error
+ ;; condition is returned
+ :wait t)
+ (cond (process
+ ;; remember the listener so we can kill it later
+ (setf (server-listener server) process))
+ (condition
+ (error condition))))
+ #+(and :unix (not :win32))
+ (when setgid
+ ;; we must make sure to call setgid before we call setuid or
+ ;; suddenly we aren't root anymore...
+ (etypecase setgid
+ (integer (setgid setgid))
+ (string (setgid (get-gid-from-name setgid)))))
+ #+(and :unix (not :win32))
+ (when setuid
+ (etypecase setuid
+ (integer (setuid setuid))
+ (string (setuid (get-uid-from-name setuid)))))
+ server)))
+
+(defun stop-server (server)
+ "Stops the Hunchentoot server SERVER."
+ ;; use lock so that the listener can't start new workers
+ (with-lock ((server-lock server))
+ ;; kill all worker threads
+ (dolist (worker (server-workers server))
+ (ignore-errors (process-kill worker))
+ (process-allow-scheduling))
+ ;; finally, kill main listener
+ (when-let (listener (server-listener server))
+ (process-kill listener)))
+ (values))
+
+(defun process-connection (server handle)
+ "This function is called by the server in a newly-created thread
+with the SERVER object itself and a socket 'handle' from which a
+stream can be created. It reads the request headers and hands over to
+PROCESS-REQUEST. This is done in a loop until the stream has to be
+closed or until a read timeout occurs."
+ (handler-bind ((error
+ ;; abort if there's an error which isn't caught inside
+ (lambda (cond)
+ (log-message *lisp-errors-log-level*
+ "Error while processing connection: ~A" cond)
+ (return-from process-connection)))
+ (warning
+ ;; log all warnings which aren't caught inside
+ (lambda (cond)
+ (log-message *lisp-warnings-log-level*
+ "Warning while processing connection: ~A" cond))))
+ (with-debugger
+ (let (*hunchentoot-stream* *local-host* *remote-host* *remote-port*)
+ (unwind-protect
+ ;; bind important special variables
+ (let ((*server* server))
+ ;; create binary stream from socket handle
+ (multiple-value-setq (*hunchentoot-stream* *local-host* *remote-host* *remote-port*)
+ (make-socket-stream handle
+ (server-read-timeout server)
+ (server-write-timeout server)))
+ ;; attach SSL to the stream if necessary
+ #-:hunchentoot-no-ssl
+ (when (server-ssl-certificate-file server)
+ #+:lispworks
+ (make-ssl-server-stream *hunchentoot-stream*
+ :certificate-file (server-ssl-certificate-file server)
+ :privatekey-file (server-ssl-privatekey-file server)
+ :privatekey-password (server-ssl-privatekey-password server))
+ #-:lispworks
+ (setq *hunchentoot-stream*
+ (cl+ssl:make-ssl-server-stream *hunchentoot-stream*
+ :certificate (server-ssl-certificate-file server)
+ :key (server-ssl-privatekey-file server))))
+ ;; wrap with chunking-enabled stream if necessary
+ (when (or (server-input-chunking-p server)
+ (server-output-chunking-p server))
+ (setq *hunchentoot-stream* (make-chunked-stream *hunchentoot-stream*)))
+ ;; now wrap with flexi stream with "faithful" external format
+ (setq *hunchentoot-stream*
+ (make-flexi-stream *hunchentoot-stream* :external-format +latin-1+))
+ ;; loop until we have to close the stream - as
+ ;; determined by *CLOSE-HUNCHENTOOT-STREAM*
+ (unwind-protect
+ (loop
+ (let ((*close-hunchentoot-stream* t))
+ ;; reset to "faithful" format on each iteration
+ ;; and reset bound of stream as well
+ (setf (flexi-stream-external-format *hunchentoot-stream*) +latin-1+
+ (flexi-stream-bound *hunchentoot-stream*) nil)
+ (multiple-value-bind (headers-in content-stream method url-string server-protocol)
+ (get-request-data)
+ (unless (and ;; check if there was a request at all
+ (cond ((server-mod-lisp-p server) headers-in)
+ (t method))
+ (prog1
+ (process-request headers-in content-stream method
+ url-string server-protocol)
+ ;; always turn chunking off at this point
+ (when (or (server-input-chunking-p server)
+ (server-output-chunking-p server))
+ (setf (chunked-stream-output-chunking-p
+ (flexi-stream-stream *hunchentoot-stream*)) nil
+ (chunked-stream-input-chunking-p
+ (flexi-stream-stream *hunchentoot-stream*)) nil))
+ (force-output* *hunchentoot-stream*))
+ ;; continue until we have to close
+ ;; the stream
+ (not *close-hunchentoot-stream*))
+ (return)))))
+ (ignore-errors (force-output* *hunchentoot-stream*))))
+ (when *hunchentoot-stream*
+ (ignore-errors (close *hunchentoot-stream* :abort t)))
+ (ignore-errors
+ (with-lock ((server-lock server))
+ ;; remove this worker from the list of all workers
+ (setf (server-workers server)
+ (delete *current-process* (server-workers server))))))))))
+
+(defun process-request (headers-in content-stream method url-string server-protocol)
+ "This function is called by PROCESS-CONNECTION after the incoming
+headers have been read. It sets up the REQUEST and REPLY objects,
+dispatches to a handler, and finally sends the output to the client
+using START-OUTPUT. If all goes as planned, the function returns T."
+ (let (*tmp-files* *headers-sent*)
+ (unwind-protect
+ (progn
+ (when (server-input-chunking-p *server*)
+ (let ((transfer-encodings (cdr (assoc :transfer-encoding headers-in))))
+ (when transfer-encodings
+ (setq transfer-encodings
+ (split "\\s*,\\*" transfer-encodings)))
+ (when (member "chunked" transfer-encodings :test #'equalp)
+ ;; turn chunking on before we read the request body
+ (setf (chunked-stream-input-chunking-p
+ (flexi-stream-stream *hunchentoot-stream*)) t))))
+ (let* ((*session* nil)
+ ;; first create a REPLY object so we can immediately start
+ ;; logging \(in case we're logging to mod_lisp)
+ (*reply* (make-instance 'reply))
+ (*request* (make-instance 'request
+ :headers-in headers-in
+ :content-stream content-stream
+ :method method
+ :uri url-string
+ :server-protocol server-protocol))
+ (*dispatch-table* (or (server-dispatch-table *server*)
+ (funcall *meta-dispatcher* *server*)))
+ backtrace)
+ (multiple-value-bind (body error)
+ (catch 'handler-done
+ (handler-bind ((error
+ (lambda (cond)
+ ;; only generate backtrace if needed
+ (setq backtrace
+ (and (or (and *show-lisp-errors-p*
+ *show-lisp-backtraces-p*)
+ (and *log-lisp-errors-p*
+ *log-lisp-backtraces-p*))
+ (get-backtrace cond)))
+ (when *log-lisp-errors-p*
+ (log-message *lisp-errors-log-level*
+ "~A~:[~*~;~%~A~]"
+ cond
+ *log-lisp-backtraces-p*
+ backtrace))
+ ;; if the headers were already sent
+ ;; the error happens within the body
+ ;; and we have to close the stream
+ (when *headers-sent*
+ (setq *close-hunchentoot-stream* t))
+ (throw 'handler-done
+ (values nil cond))))
+ (warning
+ (lambda (cond)
+ (when *log-lisp-warnings-p*
+ (log-message *lisp-warnings-log-level*
+ "~A~:[~*~;~%~A~]"
+ cond
+ *log-lisp-backtraces-p*
+ backtrace)))))
+ (with-debugger
+ ;; skip dispatch if bad request
+ (when (eq (return-code) +http-ok+)
+ ;; now do the work
+ (dispatch-request *dispatch-table*)))))
+ (when error
+ (setf (return-code *reply*)
+ +http-internal-server-error+))
+ (start-output (cond ((and error *show-lisp-errors-p*)
+ (format nil "<pre>~A~:[~*~;~%~%~A~]</pre>"
+ (escape-for-html (format nil "~A" error))
+ *show-lisp-backtraces-p*
+ (escape-for-html (format nil "~A" backtrace))))
+ (error
+ "An error has occured")
+ (t body))))
+ t))
+ (dolist (path *tmp-files*)
+ (when (and (pathnamep path) (probe-file path))
+ (ignore-errors (delete-file path)))))))
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/server.lisp
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/session.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/session.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/session.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,286 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/session.lisp,v 1.11 2007/06/04 19:24:12 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(let ((session-id-counter 0))
+ (defun get-next-session-id ()
+ "Returns the next sequential session id."
+ (incf session-id-counter)))
+
+(let ((global-session-usage-counter 0))
+ (defun count-session-usage ()
+ "Counts session usage globally and triggers session gc if necessary."
+ (when (and *session-gc-frequency*
+ (zerop (mod (incf global-session-usage-counter)
+ *session-gc-frequency*)))
+ (session-gc))))
+
+
+(defclass session ()
+ ((session-id :initform (get-next-session-id)
+ :reader session-id
+ :type integer
+ :documentation "The unique ID \(an INTEGER) of the session.")
+ (session-string :reader session-string
+ :documentation "The session strings encodes enough
+data to safely retrieve this session. It is sent to the browser as a
+cookie value or as a GET parameter.")
+ (user-agent :initform (user-agent *request*)
+ :reader session-user-agent
+ :documentation "The incoming 'User-Agent' header that
+was sent when this session was created.")
+ (remote-addr :initform (real-remote-addr *request*)
+ :reader session-remote-addr
+ :documentation "The remote IP address of the client when
+this sessions was started as returned by REAL-REMOTE-ADDR.")
+ (session-start :initform (get-universal-time)
+ :reader session-start
+ :documentation "The time this session was started.")
+ (last-click :initform (get-universal-time)
+ :reader session-last-click
+ :documentation "The last time this session was used.")
+ (session-data :initarg :session-data
+ :initform nil
+ :reader session-data
+ :documentation "Data associated with this session -
+see SESSION-VALUE.")
+ (session-counter :initform 0
+ :reader session-counter
+ :documentation "The number of times this session
+has been used.")
+ (max-time :initarg :max-time
+ :initform *session-max-time*
+ :accessor session-max-time
+ :type fixnum
+ :documentation "The time \(in seconds) after which this
+session expires if it's not used."))
+ (:documentation "SESSION objects are automatically maintained
+by Hunchentoot. They should not be created explicitly with
+MAKE-INSTANCE but implicitly with START-SESSION. Note that
+SESSION objects can only be created when the special variable
+*REQUEST* is bound to a REQUEST object."))
+
+(defun encode-session-string (id user-agent remote-addr start)
+ "Create a uniquely encoded session string based on the values ID,
+USER-AGENT, REMOTE-ADDR, and START"
+ ;; *SESSION-SECRET* is used twice due to known theoretical
+ ;; vulnerabilities of MD5 encoding
+ (md5-hex (concatenate 'string
+ *session-secret*
+ (md5-hex (format nil "~A~A~@[~A~]~@[~A~]~A"
+ *session-secret*
+ id
+ (and *use-user-agent-for-sessions*
+ user-agent)
+ (and *use-remote-addr-for-sessions*
+ remote-addr)
+ start)))))
+
+(defun stringify-session (session)
+ "Creates a string representing the SESSION object SESSION. See
+ENCODE-SESSION-STRING."
+ (encode-session-string (session-id session)
+ (session-user-agent session)
+ (session-remote-addr session)
+ (session-start session)))
+
+(defmethod initialize-instance :after ((session session) &rest init-args)
+ "Set SESSION-STRING slot after the session has been initialized."
+ (declare (ignore init-args))
+ (setf (slot-value session 'session-string) (stringify-session session)))
+
+(defun session-gc ()
+ "Removes sessions from *session-data* which are too old - see
+SESSION-TOO-OLD-P."
+ (with-lock (*session-data-lock*)
+ (setq *session-data*
+ (loop for id-session-pair in *session-data*
+ for (nil . session) = id-session-pair
+ when (session-too-old-p session)
+ do (funcall *session-removal-hook* session)
+ else
+ collect id-session-pair)))
+ (values))
+
+(defun session-value (symbol &optional (session *session*))
+ "Returns the value associated with SYMBOL from the session object
+SESSION \(the default is the current session) if it exists."
+ (when session
+ (let ((found (assoc symbol (session-data session))))
+ (values (cdr found) found))))
+
+(defsetf session-value (symbol &optional session)
+ (new-value)
+ "Sets the value associated with SYMBOL from the session object
+SESSION. If there is already a value associated with SYMBOL it will be
+replaced. Will automatically start a session if none was supplied and
+there's no session for the current request."
+ (with-rebinding (symbol)
+ (with-unique-names (place %session)
+ `(with-lock (*session-data-lock*)
+ (let* ((,%session (or ,session (start-session)))
+ (,place (assoc ,symbol (session-data ,%session))))
+ (cond
+ (,place
+ (setf (cdr ,place) ,new-value))
+ (t
+ (push (cons ,symbol ,new-value)
+ (slot-value ,%session 'session-data))
+ ,new-value)))))))
+
+(defun delete-session-value (symbol &optional (session *session*))
+ "Removes the value associated with SYMBOL from the current session
+object if there is one."
+ (when session
+ (setf (slot-value session 'session-data)
+ (delete symbol (session-data session)
+ :key #'car :test #'eq)))
+ (values))
+
+(defun session-cookie-value (&optional (session (session *request*)))
+ "Returns a string which can be used to safely restore the
+session if as session has already been established. This is used
+as the value stored in the session cookie or in the corresponding
+GET parameter."
+ (and session
+ (format nil
+ "~A:~A"
+ (session-id session)
+ (session-string session))))
+
+(defun start-session ()
+ "Returns the current SESSION object. If there is no current session,
+creates one and updates the corresponding data structures. In this
+case the function will also send a session cookie to the browser."
+ (count-session-usage)
+ (let ((session (session *request*)))
+ (when session
+ (return-from start-session session))
+ (setf session (make-instance 'session)
+ (session *request*) session)
+ (with-lock (*session-data-lock*)
+ (setq *session-data* (acons (session-id session) session *session-data*)))
+ (set-cookie *session-cookie-name*
+ :value (session-cookie-value session)
+ :path "/")
+ (setq *session* session)))
+
+(defun remove-session (session)
+ "Completely removes the SESSION object SESSION from Hunchentoot's
+internal session database."
+ (with-lock (*session-data-lock*)
+ (funcall *session-removal-hook* session)
+ (setq *session-data*
+ (delete (session-id session) *session-data*
+ :key #'car :test #'=)))
+ (values))
+
+(defun session-too-old-p (session)
+ "Returns true if the SESSION object SESSION has not been active in
+the last \(SESSION-MAX-TIME SESSION) seconds."
+ (< (+ (session-last-click session) (session-max-time session))
+ (get-universal-time)))
+
+(defun get-stored-session (id)
+ "Returns the SESSION object corresponding to the number ID if the
+session has not expired. Will remove the session if it has expired but
+will not create a new one."
+ (let ((session
+ (cdr (assoc id *session-data* :test #'=))))
+ (when (and session
+ (session-too-old-p session))
+ (when *reply*
+ (log-message :notice "Session with ID ~A too old" id))
+ (remove-session session)
+ (setq session nil))
+ session))
+
+(defun session-verify (request)
+ "Tries to get a session identifier from the cookies \(or
+alternatively from the GET parameters) sent by the client. This
+identifier is then checked for validity against the REQUEST object
+REQUEST. On success the corresponding session object \(if not too old)
+is returned \(and updated). Otherwise NIL is returned."
+ (let ((session-identifier (or (cookie-in *session-cookie-name* request)
+ (get-parameter *session-cookie-name* request))))
+ (unless (and session-identifier
+ (stringp session-identifier)
+ (plusp (length session-identifier)))
+ (return-from session-verify nil))
+ (destructuring-bind (id-string session-string)
+ (split ":" session-identifier :limit 2)
+ (let* ((id (and (scan "^\\d+$" id-string)
+ (parse-integer id-string
+ :junk-allowed t)))
+ (session (and id
+ (get-stored-session id)))
+ (user-agent (user-agent request))
+ (remote-addr (remote-addr request)))
+ (unless (and session
+ session-string
+ (string= session-string
+ (session-string session))
+ (string= session-string
+ (encode-session-string id
+ user-agent
+ (real-remote-addr request)
+ (session-start session))))
+ (when *reply*
+ (cond ((null session)
+ (log-message :notice "No session for session identifier '~A' (User-Agent: '~A', IP: '~A')"
+ session-identifier user-agent remote-addr))
+ (t
+ (log-message :warning "Fake session identifier '~A' (User-Agent: '~A', IP: '~A')"
+ session-identifier user-agent remote-addr))))
+ (when session
+ (remove-session session))
+ (return-from session-verify nil))
+ (incf (slot-value session 'session-counter))
+ (setf (slot-value session 'last-click) (get-universal-time))
+ session))))
+
+(defun reset-sessions ()
+ "Removes ALL stored sessions and creates a new session secret."
+ (reset-session-secret)
+ (with-lock (*session-data-lock*)
+ (loop for (nil . session) in *session-data*
+ do (funcall *session-removal-hook* session))
+ (setq *session-data* nil))
+ (values))
+
+(defmacro do-sessions ((var &optional result-form) &body body)
+ "Executes BODY with VAR bound to each existing SESSION object
+consecutively. Returns the values returned by RESULT-FORM unless
+RETURN is executed. The scope of the binding of VAR does not include
+RESULT-FORM."
+ (let ((=temp= (gensym)))
+ `(dolist (,=temp= *session-data* ,result-form)
+ (let ((,var (cdr ,=temp=)))
+ ,@body))))
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/specials.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/specials.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/specials.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,385 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/specials.lisp,v 1.31 2007/11/08 20:07:58 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(eval-when (:compile-toplevel :execute :load-toplevel)
+ (defmacro defvar-unbound (name &optional (doc-string ""))
+ "Convenience macro to declare unbound special variables with a
+documentation string."
+ `(progn
+ (defvar ,name)
+ (setf (documentation ',name 'variable) ,doc-string)))
+
+ (defvar *http-reason-phrase-map* (make-hash-table)
+ "Used to map numerical return codes to reason phrases.")
+
+ (defmacro def-http-return-code (name value reason-phrase)
+ "Shortcut to define constants for return codes. NAME is a
+Lisp symbol, VALUE is the numerical value of the return code, and
+REASON-PHRASE is the phrase \(a string) to be shown in the
+server's status line."
+ `(eval-when (:compile-toplevel :execute :load-toplevel)
+ (defconstant ,name ,value ,(format nil "HTTP return code \(~A) for '~A'."
+ value reason-phrase))
+ (setf (gethash ,value *http-reason-phrase-map*) ,reason-phrase))))
+
+(defconstant +crlf+ #.(format nil "~C~C" #\Return #\Linefeed)
+ "A constant string consisting of the two ASCII characters CR and LF.")
+
+(def-http-return-code +http-continue+ 100 "Continue")
+(def-http-return-code +http-switching-protocols+ 101 "Switching Protocols")
+(def-http-return-code +http-ok+ 200 "OK")
+(def-http-return-code +http-created+ 201 "Created")
+(def-http-return-code +http-accepted+ 202 "Accepted")
+(def-http-return-code +http-non-authoritative-information+ 203 "Non-Authoritative Information")
+(def-http-return-code +http-no-content+ 204 "No Content")
+(def-http-return-code +http-reset-content+ 205 "Reset Content")
+(def-http-return-code +http-partial-content+ 206 "Partial Content")
+(def-http-return-code +http-multi-status+ 207 "Multi-Status")
+(def-http-return-code +http-multiple-choices+ 300 "Multiple Choices")
+(def-http-return-code +http-moved-permanently+ 301 "Moved Permanently")
+(def-http-return-code +http-moved-temporarily+ 302 "Moved Temporarily")
+(def-http-return-code +http-see-other+ 303 "See Other")
+(def-http-return-code +http-not-modified+ 304 "Not Modified")
+(def-http-return-code +http-use-proxy+ 305 "Use Proxy")
+(def-http-return-code +http-temporary-redirect+ 307 "Temporary Redirect")
+(def-http-return-code +http-bad-request+ 400 "Bad Request")
+(def-http-return-code +http-authorization-required+ 401 "Authorization Required")
+(def-http-return-code +http-payment-required+ 402 "Payment Required")
+(def-http-return-code +http-forbidden+ 403 "Forbidden")
+(def-http-return-code +http-not-found+ 404 "Not Found")
+(def-http-return-code +http-method-not-allowed+ 405 "Method Not Allowed")
+(def-http-return-code +http-not-acceptable+ 406 "Not Acceptable")
+(def-http-return-code +http-proxy-authentication-required+ 407 "Proxy Authentication Required")
+(def-http-return-code +http-request-time-out+ 408 "Request Time-out")
+(def-http-return-code +http-conflict+ 409 "Conflict")
+(def-http-return-code +http-gone+ 410 "Gone")
+(def-http-return-code +http-length-required+ 411 "Length Required")
+(def-http-return-code +http-precondition-failed+ 412 "Precondition Failed")
+(def-http-return-code +http-request-entity-too-large+ 413 "Request Entity Too Large")
+(def-http-return-code +http-request-uri-too-large+ 414 "Request-URI Too Large")
+(def-http-return-code +http-unsupported-media-type+ 415 "Unsupported Media Type")
+(def-http-return-code +http-requested-range-not-satisfiable+ 416 "Requested range not satisfiable")
+(def-http-return-code +http-expectation-failed+ 417 "Expectation Failed")
+(def-http-return-code +http-failed-dependency+ 424 "Failed Dependency")
+(def-http-return-code +http-internal-server-error+ 500 "Internal Server Error")
+(def-http-return-code +http-not-implemented+ 501 "Not Implemented")
+(def-http-return-code +http-bad-gateway+ 502 "Bad Gateway")
+(def-http-return-code +http-service-unavailable+ 503 "Service Unavailable")
+(def-http-return-code +http-gateway-time-out+ 504 "Gateway Time-out")
+(def-http-return-code +http-version-not-supported+ 505 "Version not supported")
+
+(defvar *approved-return-codes* '(#.+http-ok+ #.+http-no-content+
+ #.+http-multi-status+
+ #.+http-not-modified+)
+ "A list of return codes the server should not treat as an error -
+see *HANDLE-HTTP-ERRORS-P*.")
+
+(defconstant +day-names+
+ #("Mon" "Tue" "Wed" "Thu" "Fri" "Sat" "Sun")
+ "The three-character names of the seven days of the week - needed
+for cookie date format.")
+
+(defconstant +month-names+
+ #("Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec")
+ "The three-character names of the twelve months - needed for cookie
+date format.")
+
+(defvar *session-cookie-name* "hunchentoot-session"
+ "The name of the cookie \(or the GET parameter) which is used to
+store the session on the client side.")
+
+(defvar *rewrite-for-session-urls* t
+ "Whether HTML pages should possibly be rewritten for cookie-less
+session-management.")
+
+(defvar *content-types-for-url-rewrite*
+ '("text/html" "application/xhtml+xml")
+ "The content types for which url-rewriting is OK. See
+*REWRITE-FOR-SESSION-URLS*.")
+
+(defparameter *the-random-state* (make-random-state t)
+ "A fresh random state.")
+
+(defvar-unbound *session-secret*
+ "A random value that's used to encode the public session data.")
+
+(defvar-unbound *hunchentoot-stream*
+ "The stream representing the socket Hunchentoot is listening on.")
+
+(defvar *close-hunchentoot-stream* nil
+ "Will be set to T if the Hunchentoot socket stream has to be
+closed at the end of the request.")
+
+(defvar *headers-sent* nil
+ "Used internally to check whether the reply headers have
+already been sent for this request.")
+
+(defvar *file-upload-hook* nil
+ "If this is not NIL, it should be a unary function which will
+be called with a pathname for each file which is uploaded to
+Hunchentoot. The pathname denotes the temporary file to which
+the uploaded file is written. The hook is called directly before
+the file is created.")
+
+(defvar *session-data* nil
+ "All sessions of all users currently using Hunchentoot. An
+alist where the car is the session's ID and the cdr is the
+SESSION object itself.")
+
+(defvar *session-max-time* #.(* 30 60)
+ "The default time \(in seconds) after which a session times out.")
+
+(defvar *session-gc-frequency* 50
+ "A session GC \(see function SESSION-GC) will happen every
+*SESSION-GC-FREQUENCY* requests \(counting only requests which
+use a session) if this variable is not NIL.")
+
+(defvar *use-user-agent-for-sessions* t
+ "Whether the 'User-Agent' header should be encoded into the session
+string. If this value is true, a session will cease to be accessible
+if the client sends a different 'User-Agent' header.")
+
+(defvar *use-remote-addr-for-sessions* nil
+ "Whether the client's remote IP \(as returned by REAL-REMOTE-ADDR)
+should be encoded into the session string. If this value is true, a
+session will cease to be accessible if the client's remote IP changes.
+
+This might for example be an issue if the client uses a proxy server
+which doesn't send correct 'X_FORWARDED_FOR' headers.")
+
+(defvar *default-content-type* "text/html; charset=iso-8859-1"
+ "The default content-type header which is returned to the client.")
+
+(defvar *methods-for-post-parameters* '(:post)
+ "A list of the request method types \(as keywords) for which
+Hunchentoot will try to compute POST-PARAMETERS.")
+
+(defvar *header-stream* nil
+ "If this variable is not NIL, it should be bound to a stream to
+which incoming and outgoing headers will be written for debugging
+purposes.")
+
+(defvar *show-lisp-errors-p* nil
+ "Whether Lisp errors should be shown in HTML output.")
+
+(defvar *show-lisp-backtraces-p* nil
+ "Whether Lisp backtraces should be shown in HTML output when an
+error occurs. Will only have an effect if *SHOW-LISP-ERRORS-P* is
+also true.")
+
+(defvar *log-lisp-errors-p* t
+ "Whether Lisp errors should be logged.")
+
+(defvar *log-lisp-warnings-p* t
+ "Whether Lisp warnings should be logged.")
+
+(defvar *log-lisp-backtraces-p* nil
+ "Whether Lisp backtraces should be logged when an error or warning
+occurs. Will only have an effect if *LOG-LISP-ERRORS-P* or
+*LOG-LISP-BACKTRACES* are also true.")
+
+(defvar *lisp-errors-log-level* :error
+ "Log level for Lisp errors.")
+
+(defvar *lisp-warnings-log-level* :warning
+ "Log level for Lisp warnings.")
+
+(defvar *show-access-log-messages* t
+ "Whether routine messages about each request should be logged. This
+will only be done if SERVER-USE-APACHE-LOG-P is NIL.")
+
+(defvar *log-file*
+ (load-time-value
+ (let ((tmp-dir
+ #+:allegro (system:temporary-directory)
+ #+:lispworks (pathname (or (lw:environment-variable "TEMP")
+ (lw:environment-variable "TMP")
+ #+:win32 "C:/"
+ #-:win32 "/tmp/"))
+ #-(or :allegro :lispworks) #p"/tmp/"))
+ (merge-pathnames "hunchentoot.log" tmp-dir)))
+ "The log file to use \(unless the Apache log is used).")
+
+(defvar *log-file-stream* nil
+ "The stream corresponding to the log file.")
+
+(defvar *log-file-lock* (make-lock "log-file-lock")
+ "A lock to prevent two threads from writing to the log file at
+same time.")
+
+(defvar-unbound *session*
+ "The current SESSION object.")
+
+(defvar-unbound *request*
+ "The current REQUEST object.")
+
+(defvar-unbound *reply*
+ "The current REPLY object.")
+
+(defvar *log-prefix* t
+ "The prefix which is printed in front of Apache log
+messages. This should be a string or T \(for \"Hunchentoot\", the
+default) or NIL \(meaning no prefix).")
+
+(defconstant +implementation-link+
+ #+:cmu "http://www.cons.org/cmucl/"
+ #+:sbcl "http://www.sbcl.org/"
+ #+:allegro "http://www.franz.com/products/allegrocl/"
+ #+:lispworks "http://www.lispworks.com/"
+ #+:openmcl "http://openmcl.clozure.com/"
+ "A link to the website of the underlying Lisp implementation.")
+
+(defvar *dispatch-table* (list 'default-dispatcher)
+ "A list of dispatch functions - see *META-DISPATCHER*.")
+
+(defvar *default-handler* 'default-handler
+ "The name of the function which is always returned by
+DEFAULT-DISPATCHER.")
+
+(defvar *easy-handler-alist* nil
+ "An alist of \(URI server-names function) lists defined by
+DEFINE-EASY-HANDLER.")
+
+(defvar *http-error-handler* nil
+ "Contains NIL \(the default) or a function of one argument which is
+called if the content handler has set a return code which is not in
+*APPROVED-RETURN-CODES* and *HANDLE-HTTP-ERRORS* is true.")
+
+(defvar *handle-http-errors-p* t
+ "A generalized boolean that determines whether return codes which
+are not in *APPROVED-HEADERS* are treated specially. When its value
+is true \(the default), either a default body for the return code or
+the result of calling *HTTP-ERROR-HANDLER* is used. When the value is
+NIL, no special action is taken and you are expected to supply your
+own response body to describe the error.")
+
+(defvar *default-log-level* nil
+ "The default log level for LOG-MESSAGE*.")
+
+(defvar *session-data-lock* (make-lock "session-data-lock")
+ "A lock to prevent two threads from modifying *SESSION-DATA* at the
+same time.")
+
+(defvar *session-removal-hook* (constantly nil)
+ "A function of one argument \(a session object) which is called
+whenever a session is garbage-collected.")
+
+(defvar *tmp-directory*
+ #+(or :win32 :mswindows) "c:\\hunchentoot-temp\\"
+ #-(or :win32 :mswindows) "/tmp/hunchentoot/"
+ "Directory for temporary files created by MAKE-TMP-FILE-NAME.")
+
+(defvar *tmp-files* nil
+ "A list of temporary files created while a request was handled.")
+
+(defconstant +latin-1+
+ (make-external-format :latin1 :eol-style :lf)
+ "A FLEXI-STREAMS external format used for `faithful' input and
+output of binary data.")
+
+(defconstant +utf-8+
+ (make-external-format :utf8 :eol-style :lf)
+ "A FLEXI-STREAMS external format used internally for logging and to
+encode cookie values.")
+
+(defvar *hunchentoot-default-external-format* +latin-1+
+ "The external format used to compute the REQUEST object.")
+
+(defconstant +buffer-length+ 8192
+ "Length of buffers used for internal purposes.")
+
+(defvar-unbound *server*
+ "During the execution of dispatchers and handlers this variable
+is bound to the SERVER object which processes the request.")
+
+(defvar *meta-dispatcher* (lambda (server)
+ (declare (ignore server))
+ *dispatch-table*)
+ "The value of this variable should be a function of one argument.
+It is called with the current Hunchentoot server instance \(unless the
+server has its own dispatch table) and must return a suitable dispatch
+table. The initial value is a function which always unconditionally
+returns *DISPATCH-TABLE*.")
+
+(defvar *server-counter* 0
+ "Internal counter used to generate meaningful names for
+listener threads.")
+
+(defvar *worker-counter* 0
+ "Internal counter used to generate meaningful names for worker
+threads.")
+
+(defvar *default-read-timeout* 20
+ "The default read-timeout used when a Hunchentoot server is
+reading from a socket stream.")
+
+(defvar *default-write-timeout* 20
+ "The default write-timeout used when a Hunchentoot server is
+writing to a socket stream.")
+
+(defvar *force-output-timeout* 30
+ "The maximal time Hunchentoot waits for FORCE-OUTPUT to
+return.")
+
+(defvar *cleanup-interval* 100
+ "Should be NIL or a positive integer. The system calls
+*CLEANUP-FUNCTION* whenever *CLEANUP-INTERVAL* new worker threads have
+been created unless the value is NIL.")
+
+(defvar *cleanup-function* 'cleanup-function
+ "The function which is called if *CLEANUP-INTERVAL* is not NIL.")
+
+(defvar-unbound *local-host*
+ "Bound to a string denoting the address at which the current
+request arrived.")
+
+(defvar-unbound *remote-host*
+ "Bound to a string denoting the address the current request
+originated from.")
+
+(defvar-unbound *remote-port*
+ "Bound to an integer denoting the port the current request
+originated from.")
+
+(pushnew :hunchentoot *features*)
+
+;; stuff for Nikodemus Siivola's HYPERDOC
+;; see <http://common-lisp.net/project/hyperdoc/>
+;; and <http://www.cliki.net/hyperdoc>
+
+(defvar *hyperdoc-base-uri* "http://weitz.de/hunchentoot/")
+
+(let ((exported-symbols-alist
+ (loop for symbol being the external-symbols of :hunchentoot
+ collect (cons symbol (concatenate 'string "#" (string-downcase symbol))))))
+ (defun hyperdoc-lookup (symbol type)
+ (declare (ignore type))
+ (cdr (assoc symbol exported-symbols-alist :test #'eq))))
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/specials.lisp
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/UTF-8-demo.html
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/UTF-8-demo.html 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/UTF-8-demo.html 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head><title>UTF-8 test file</title></head>
+ <body>
+ <p>Original by Markus Kuhn, adapted for HTML by Martin Dürst.</p>
+<pre>
+UTF-8 encoded sample plain-text file
+‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
+
+Markus Kuhn [ˈmaʳkʊs kuːn] <mkuhn(a)acm.org> — 1999-08-20
+
+
+The ASCII compatible UTF-8 encoding of ISO 10646 and Unicode
+plain-text files is defined in RFC 2279 and in ISO 10646-1 Annex R.
+
+
+Using Unicode/UTF-8, you can write in emails and source code things such as
+
+Mathematics and Sciences:
+
+ ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β),
+
+ ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (A ⇔ B),
+
+ 2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm
+
+Linguistics and dictionaries:
+
+ ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn
+ Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ]
+
+APL:
+
+ ((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈
+
+Nicer typography in plain text files:
+
+ ╔══════════════════════════════════════════╗
+ ║ ║
+ ║ • ‘single’ and “double” quotes ║
+ ║ ║
+ ║ • Curly apostrophes: “We’ve been here” ║
+ ║ ║
+ ║ • Latin-1 apostrophe and accents: '´` ║
+ ║ ║
+ ║ • ‚deutsche‘ „Anführungszeichen“ ║
+ ║ ║
+ ║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║
+ ║ ║
+ ║ • ASCII safety test: 1lI|, 0OD, 8B ║
+ ║ ╭─────────╮ ║
+ ║ • the euro symbol: │ 14.95 € │ ║
+ ║ ╰─────────╯ ║
+ ╚══════════════════════════════════════════╝
+
+Greek (in Polytonic):
+
+ The Greek anthem:
+
+ Σὲ γνωρίζω ἀπὸ τὴν κόψη
+ τοῦ σπαθιοῦ τὴν τρομερή,
+ σὲ γνωρίζω ἀπὸ τὴν ὄψη
+ ποὺ μὲ βία μετράει τὴ γῆ.
+
+ ᾿Απ᾿ τὰ κόκκαλα βγαλμένη
+ τῶν ῾Ελλήνων τὰ ἱερά
+ καὶ σὰν πρῶτα ἀνδρειωμένη
+ χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά!
+
+ From a speech of Demosthenes in the 4th century BC:
+
+ Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι,
+ ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς
+ λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ
+ τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿
+ εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ
+ πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν
+ οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι,
+ οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν
+ ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον
+ τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι
+ γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν
+ προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους
+ σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ
+ τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ
+ τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς
+ τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον.
+
+ Δημοσθένους, Γ´ ᾿Ολυνθιακὸς
+
+Georgian:
+
+ From a Unicode conference invitation:
+
+ გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო
+ კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს,
+ ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს
+ ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი,
+ ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება
+ ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში,
+ ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში.
+
+Russian:
+
+ From a Unicode conference invitation:
+
+ Зарегистрируйтесь сейчас на Десятую Международную Конференцию по
+ Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии.
+ Конференция соберет широкий круг экспертов по вопросам глобального
+ Интернета и Unicode, локализации и интернационализации, воплощению и
+ применению Unicode в различных операционных системах и программных
+ приложениях, шрифтах, верстке и многоязычных компьютерных системах.
+
+Thai (UCS Level 2):
+
+ Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese
+ classic 'San Gua'):
+
+ [----------------------------|------------------------]
+ ๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่
+ สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา
+ ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา
+ โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ
+ เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ
+ ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ
+ พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้
+ ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ
+
+ (The above is a two-column text. If combining characters are handled
+ correctly, the lines of the second column should be aligned with the
+ | character above.)
+
+Ethiopian:
+
+ Proverbs in the Amharic language:
+
+ ሰማይ አይታረስ ንጉሥ አይከሰስ።
+ ብላ ካለኝ እንደአባቴ በቆመጠኝ።
+ ጌጥ ያለቤቱ ቁምጥና ነው።
+ ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው።
+ የአፍ ወለምታ በቅቤ አይታሽም።
+ አይጥ በበላ ዳዋ ተመታ።
+ ሲተረጉሙ ይደረግሙ።
+ ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል።
+ ድር ቢያብር አንበሳ ያስር።
+ ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም።
+ እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም።
+ የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ።
+ ሥራ ከመፍታት ልጄን ላፋታት።
+ ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል።
+ የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ።
+ ተንጋሎ ቢተፉ ተመልሶ ባፉ።
+ ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው።
+ እግርህን በፍራሽህ ልክ ዘርጋ።
+
+Runes:
+
+ ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ
+
+ (Old English, which transcribed into Latin reads 'He cwaeth that he
+ bude thaem lande northweardum with tha Westsae.' and means 'He said
+ that he lived in the northern land near the Western Sea.')
+
+Braille:
+
+ ⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌
+
+ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞
+ ⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎
+ ⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂
+ ⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙
+ ⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑
+ ⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲
+
+ ⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
+
+ ⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹
+ ⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞
+ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕
+ ⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹
+ ⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎
+ ⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎
+ ⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳
+ ⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞
+ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
+
+ (The first couple of paragraphs of "A Christmas Carol" by Dickens)
+
+Compact font selection example text:
+
+ ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789
+ abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ
+ –—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд
+ ∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა
+
+Greetings in various languages:
+
+ Hello world, Καλημέρα κόσμε, コンニチハ
+
+Box drawing alignment tests: █
+ ▉
+ ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
+ ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
+ ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
+ ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
+ ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
+ ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
+ ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
+
+</pre>
+</body>
+</html>
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/favicon.ico
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/favicon.ico
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/fz.jpg
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/fz.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/packages.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/packages.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/packages.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,37 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/test/packages.lisp,v 1.4 2007/01/01 23:50:32 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :cl-user)
+
+(defpackage :hunchentoot-test
+ (:nicknames :tbnl-test)
+ (:use :cl :cl-who :hunchentoot))
+
+(defpackage :hunchentoot-test-user
+ (:use :cl :hunchentoot))
\ No newline at end of file
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/packages.lisp
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/test.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/test.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/test/test.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,582 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/test/test.lisp,v 1.20 2007/09/18 14:24:01 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot-test)
+
+(defvar *this-file* (load-time-value
+ (or #.*compile-file-pathname* *load-pathname*)))
+
+(defmacro with-html (&body body)
+ `(with-html-output-to-string (*standard-output* nil :prologue t)
+ ,@body))
+
+(defun hunchentoot-link ()
+ (with-html-output (*standard-output*)
+ (:a :href "http://weitz.de/hunchentoot/" "Hunchentoot")))
+
+(defun menu-link ()
+ (with-html-output (*standard-output*)
+ (:p (:hr
+ (:a :href "/hunchentoot/test" "Back to menu")))))
+
+(defmacro with-lisp-output ((var) &body body)
+ `(let ((*package* (find-package :hunchentoot-test-user)))
+ (with-output-to-string (,var #+:lispworks nil
+ #+:lispworks :element-type
+ #+:lispworks 'lw:simple-char)
+ ,@body)))
+
+(defmacro info-table (&rest forms)
+ (let ((=value= (gensym))
+ (=first= (gensym)))
+ `(with-html-output (*standard-output*)
+ (:p (:table :border 1 :cellpadding 2 :cellspacing 0
+ (:tr (:td :colspan 2
+ "Some Information "
+ (hunchentoot-link)
+ " provides about this request:"))
+ ,@(loop for form in forms
+ collect `(:tr (:td :valign "top"
+ (:pre :style "padding: 0px"
+ (esc (with-lisp-output (s) (pprint ',form s)))))
+ (:td :valign "top"
+ (:pre :style "padding: 0px"
+ (esc (with-lisp-output (s)
+ (loop for ,=value= in (multiple-value-list ,form)
+ for ,=first= = t then nil
+ unless ,=first=
+ do (princ ", " s)
+ do (pprint ,=value= s))))))))))
+ (menu-link))))
+
+(defun authorization-page ()
+ (multiple-value-bind (user password)
+ (authorization)
+ (cond ((and (equal user "nanook")
+ (equal password "igloo"))
+ (with-html
+ (:html
+ (:head (:title "Hunchentoot page with Basic Authentication"))
+ (:body
+ (:h2 (hunchentoot-link)
+ " page with Basic Authentication")
+ (info-table (header-in "Authorization")
+ (authorization))))))
+ (t
+ (require-authorization)))))
+
+(defparameter *test-image*
+ (load-time-value
+ (with-open-file (in (make-pathname :name "fz" :type "jpg" :version nil
+ :defaults *this-file*)
+ :element-type '(unsigned-byte 8))
+ (let ((image-data (make-array (file-length in)
+ :element-type '(unsigned-byte 8))))
+ (read-sequence image-data in)
+ image-data))))
+
+(defun image-ram-page ()
+ (setf (content-type)
+ "image/jpeg")
+ *test-image*)
+
+(let ((count 0))
+ (defun info ()
+ (with-html
+ (:html
+ (:head (:title "Hunchentoot Information"))
+ (:body
+ (:h2 (hunchentoot-link) " Information Page")
+ (:p "This page has been called "
+ (:b
+ (fmt "~[~;once~;twice~:;~:*~R times~]" (incf count)))
+ " since its handler was compiled.")
+ (info-table (host)
+ (server-address *server*)
+ (server-addr)
+ (server-port)
+ (remote-addr)
+ (remote-port)
+ (real-remote-addr)
+ (request-method)
+ (script-name)
+ (query-string)
+ (get-parameters)
+ (headers-in)
+ (cookies-in)
+ (user-agent)
+ (referer)
+ (request-uri)
+ (server-protocol)
+ (mod-lisp-id)
+ (ssl-session-id)))))))
+
+(defun oops ()
+ (with-html
+ (dotimes (i 3)
+ (log-message* "Oops (default) # ~a" i))
+ (log-message :emerg "Oops emergency")
+ (log-message :alert "Oops alert")
+ (log-message :crit "Oops critical")
+ (log-message :error "Oops error")
+ (log-message :warning "Oops warning")
+ (log-message :notice "Oops notice")
+ (log-message :info "Oops info")
+ (log-message :debug "Oops debug")
+ (error "An error was triggered on purpose. Check your ~
+Apache error log. Up to 12 messages where logged depending on ~
+the Apache log level set in httpd.conf.")
+ (:html
+ (:body "You'll never see this sentence..."))))
+
+(defun redir ()
+ (redirect "/hunchentoot/test/info.html?redirected=1"))
+
+(defun forbidden ()
+ (setf (return-code *reply*) +http-forbidden+)
+ nil)
+
+(defun cookie-test ()
+ (set-cookie "pumpkin" :value "barking")
+ (no-cache)
+ (with-html
+ (:html
+ (:head (:title "Hunchentoot cookie test"))
+ (:body
+ (:h2 (hunchentoot-link)
+ " cookie test")
+ (:p "You might have to reload this page to see the cookie value.")
+ (info-table (cookie-in "pumpkin")
+ (mapcar #'car (cookies-in)))))))
+
+(defun session-test ()
+ (let ((new-foo-value (post-parameter "new-foo-value")))
+ (when new-foo-value
+ (setf (session-value 'foo) new-foo-value)))
+ (let ((new-bar-value (post-parameter "new-bar-value")))
+ (when new-bar-value
+ (setf (session-value 'bar) new-bar-value)))
+ (no-cache)
+ (with-html
+ (:html
+ (:head (:title "Hunchentoot session test"))
+ (:body
+ (:h2 (hunchentoot-link)
+ " session test")
+ (:p "Use the forms below to set new values for "
+ (:code "FOO")
+ " or "
+ (:code "BAR")
+ ". You can later return to this page to check if
+they're still set. Also, try to use another browser at the same
+time or try with cookies disabled.")
+ (:p (:form :method :post
+ "New value for "
+ (:code "FOO")
+ ": "
+ (:input :type :text
+ :name "new-foo-value"
+ :value (or (session-value 'foo) ""))))
+ (:p (:form :method :post
+ "New value for "
+ (:code "BAR")
+ ": "
+ (:input :type :text
+ :name "new-bar-value"
+ :value (or (session-value 'bar) ""))))
+ (info-table *session-cookie-name*
+ (cookie-in *session-cookie-name*)
+ (mapcar #'car (cookies-in))
+ (session-value 'foo)
+ (session-value 'bar))))))
+
+(defun parameter-test (&key (method :get) (charset :iso-8859-1))
+ (no-cache)
+ (recompute-request-parameters :external-format
+ (flexi-streams:make-external-format charset :eol-style :lf))
+ (setf (content-type)
+ (format nil "text/html; charset=~A" charset))
+ (with-html
+ (:html
+ (:head (:title (fmt "Hunchentoot ~A parameter test" method)))
+ (:body
+ (:h2 (hunchentoot-link)
+ (fmt " ~A parameter test with charset ~A" method charset))
+ (:p "Enter some non-ASCII characters in the input field below
+and see what's happening.")
+ (:p (:form
+ :method method
+ "Enter a value: "
+ (:input :type :text
+ :name "foo")))
+ (case method
+ (:get (info-table (query-string)
+ (map 'list #'char-code (get-parameter "foo"))
+ (get-parameter "foo")))
+ (:post (info-table (raw-post-data)
+ (map 'list #'char-code (post-parameter "foo"))
+ (post-parameter "foo"))))))))
+
+(defun parameter-test-latin1-get ()
+ (parameter-test :method :get :charset :iso-8859-1))
+
+(defun parameter-test-latin1-post ()
+ (parameter-test :method :post :charset :iso-8859-1))
+
+(defun parameter-test-utf8-get ()
+ (parameter-test :method :get :charset :utf-8))
+
+(defun parameter-test-utf8-post ()
+ (parameter-test :method :post :charset :utf-8))
+
+;; this should not be the same directory as *TMP-DIRECTORY* and it
+;; should be initially empty (or non-existent)
+(defvar *tmp-test-directory*
+ #+(or :win32 :mswindows) #p"c:\\hunchentoot-temp\\test\\"
+ #-(or :win32 :mswindows) #p"/tmp/hunchentoot/test/")
+
+(defvar *tmp-test-files* nil)
+
+(let ((counter 0))
+ (defun handle-file (post-parameter)
+ (when (and post-parameter
+ (listp post-parameter))
+ (destructuring-bind (path file-name content-type)
+ post-parameter
+ (let ((new-path (make-pathname :name (format nil "hunchentoot-test-~A"
+ (incf counter))
+ :type nil
+ :defaults *tmp-test-directory*)))
+ ;; strip directory info sent by Windows browsers
+ (when (search "Windows" (user-agent) :test #'char-equal)
+ (setq file-name (cl-ppcre:regex-replace ".*\\\\" file-name "")))
+ (rename-file path (ensure-directories-exist new-path))
+ (push (list new-path file-name content-type) *tmp-test-files*))))))
+
+(defun clean-tmp-dir ()
+ (loop for (path . nil) in *tmp-test-files*
+ when (probe-file path)
+ do (ignore-errors (delete-file path)))
+ (setq *tmp-test-files* nil))
+
+(defun upload-test ()
+ (let (post-parameter-p)
+ (when (post-parameter "file1")
+ (handle-file (post-parameter "file1"))
+ (setq post-parameter-p t))
+ (when (post-parameter "file2")
+ (handle-file (post-parameter "file2"))
+ (setq post-parameter-p t))
+ (when (post-parameter "clean")
+ (clean-tmp-dir)
+ (setq post-parameter-p t))
+ (when post-parameter-p
+ ;; redirect so user can safely use 'Back' button
+ (redirect (script-name))))
+ (no-cache)
+ (with-html
+ (:html
+ (:head (:title "Hunchentoot file upload test"))
+ (:body
+ (:h2 (hunchentoot-link)
+ " file upload test")
+ (:form :method :post :enctype "multipart/form-data"
+ (:p "First file: "
+ (:input :type :file
+ :name "file1"))
+ (:p "Second file: "
+ (:input :type :file
+ :name "file2"))
+ (:p (:input :type :submit)))
+ (when *tmp-test-files*
+ (htm
+ (:p
+ (:table :border 1 :cellpadding 2 :cellspacing 0
+ (:tr (:td :colspan 3 (:b "Uploaded files")))
+ (loop for (path file-name nil) in *tmp-test-files*
+ for counter from 1
+ do (htm
+ (:tr (:td :align "right" (str counter))
+ (:td (:a :href (format nil "files/~A?path=~A"
+ (url-encode file-name)
+ (url-encode (namestring path)))
+ (esc file-name)))
+ (:td :align "right"
+ (str (ignore-errors
+ (with-open-file (in path)
+ (file-length in))))
+ " Bytes"))))))
+ (:form :method :post
+ (:p (:input :type :submit :name "clean" :value "Delete uploaded files")))))
+ (menu-link)))))
+
+(defun send-file ()
+ (let* ((path (get-parameter "path"))
+ (file-info (and path
+ (find (pathname path) *tmp-test-files*
+ :key #'first :test #'equal))))
+ (unless file-info
+ (setf (return-code *reply*)
+ +http-not-found+)
+ (return-from send-file))
+ (handle-static-file path (third file-info))))
+
+(defparameter *headline*
+ (load-time-value
+ (format nil "Hunchentoot test menu (see file <code>~A</code>)"
+ (merge-pathnames (make-pathname :type "lisp") *this-file*))))
+
+(defvar *utf-8* (flex:make-external-format :utf-8 :eol-style :lf))
+
+(defvar *utf-8-file* (merge-pathnames "UTF-8-demo.html" *this-file*)
+ "Demo file stolen from <http://www.w3.org/2001/06/utf-8-test/>.")
+
+(defun stream-direct ()
+ (setf (content-type) "text/html; charset=utf-8")
+ (let ((stream (send-headers))
+ (buffer (make-array 1024 :element-type '(unsigned-byte 8))))
+ (with-open-file (in *utf-8-file*
+ :element-type '(unsigned-byte 8))
+ (loop for pos = (read-sequence buffer in)
+ until (zerop pos)
+ do (write-sequence buffer stream :end pos)))))
+
+(defun stream-direct-utf-8 ()
+ (setf (content-type) "text/html; charset=utf-8")
+ (let ((stream (send-headers)))
+ (setf (flex:flexi-stream-external-format stream) *utf-8*)
+ (with-open-file (in (merge-pathnames "UTF-8-demo.html" *this-file*)
+ :element-type '(unsigned-byte 8))
+ (setq in (flex:make-flexi-stream in :external-format *utf-8*))
+ (loop for line = (read-line in nil nil)
+ while line
+ do (write-line line stream)))))
+
+(defun stream-direct-utf-8-string ()
+ (setf (content-type) "text/html; charset=utf-8"
+ (reply-external-format) *utf-8*)
+ (with-open-file (in (merge-pathnames "UTF-8-demo.html" *this-file*)
+ :element-type '(unsigned-byte 8))
+ (let ((string (make-array (file-length in)
+ :element-type #-:lispworks 'character #+:lispworks 'lw:simple-char
+ :fill-pointer t)))
+ (setf in (flex:make-flexi-stream in :external-format *utf-8*)
+ (fill-pointer string) (read-sequence string in))
+ string)))
+
+(define-easy-handler (easy-demo :uri "/hunchentoot/test/easy-demo.html"
+ :default-request-type :post)
+ (first-name last-name
+ (age :parameter-type 'integer)
+ (implementation :parameter-type 'keyword)
+ (meal :parameter-type '(hash-table boolean))
+ (team :parameter-type 'list))
+ (with-html
+ (:html
+ (:head (:title "Hunchentoot \"easy\" handler example"))
+ (:body
+ (:h2 (hunchentoot-link)
+ " \"Easy\" handler example")
+ (:p (:form :method :post
+ (:table :border 1 :cellpadding 2 :cellspacing 0
+ (:tr
+ (:td "First Name:")
+ (:td (:input :type :text
+ :name "first-name"
+ :value (or first-name "Donald"))))
+ (:tr
+ (:td "Last name:")
+ (:td (:input :type :text
+ :name "last-name"
+ :value (or last-name "Duck"))))
+ (:tr
+ (:td "Age:")
+ (:td (:input :type :text
+ :name "age"
+ :value (or age 42))))
+ (:tr
+ (:td "Implementation:")
+ (:td (:select :name "implementation"
+ (loop for (value option) in '((:lispworks "LispWorks")
+ (:allegro "AllegroCL")
+ (:cmu "CMUCL")
+ (:sbcl "SBCL")
+ (:openmcl "OpenMCL"))
+ do (htm
+ (:option :value value
+ :selected (eq value implementation)
+ (str option)))))))
+ (:tr
+ (:td :valign :top "Meal:")
+ (:td (loop for choice in '("Burnt weeny sandwich"
+ "Canard du jour"
+ "Easy meat"
+ "Muffin"
+ "Twenty small cigars"
+ "Yellow snow")
+ do (htm
+ (:input :type "checkbox"
+ :name (format nil "meal{~A}" choice)
+ :checked (gethash choice meal)
+ (esc choice))
+ (:br)))))
+ (:tr
+ (:td :valign :top "Team:")
+ (:td (loop for player in '("Beckenbauer"
+ "Cruyff"
+ "Maradona"
+ ;; without accent (for SBCL)
+ "Pele"
+ "Zidane")
+ do (htm
+ (:input :type "checkbox"
+ :name "team"
+ :value player
+ :checked (member player team :test #'string=)
+ (esc player))
+ (:br)))))
+ (:tr
+ (:td :colspan 2
+ (:input :type "submit"))))))
+ (info-table first-name
+ last-name
+ age
+ implementation
+ (loop :for choice :being :the :hash-keys :of meal :collect choice)
+ (gethash "Yellow snow" meal)
+ team)))))
+
+
+(defun menu ()
+ (with-html
+ (:html
+ (:head
+ (:link :rel "shortcut icon"
+ :href "/hunchentoot/test/favicon.ico" :type "image/x-icon")
+ (:title "Hunchentoot test menu"))
+ (:body
+ (:h2 (str *headline*))
+ (:table :border 0 :cellspacing 4 :cellpadding 4
+ (:tr (:td (:a :href "/hunchentoot/test/info.html?foo=bar"
+ "Info provided by Hunchentoot")))
+ (:tr (:td (:a :href "/hunchentoot/test/cookie.html"
+ "Cookie test")))
+ (:tr (:td (:a :href "/hunchentoot/test/session.html"
+ "Session test")))
+ (:tr (:td (:a :href "/hunchentoot/test/parameter_latin1_get.html"
+ "GET parameter handling with LATIN-1 charset")))
+ (:tr (:td (:a :href "/hunchentoot/test/parameter_latin1_post.html"
+ "POST parameter handling with LATIN-1 charset")))
+ (:tr (:td (:a :href "/hunchentoot/test/parameter_utf8_get.html"
+ "GET parameter handling with UTF-8 charset")))
+ (:tr (:td (:a :href "/hunchentoot/test/parameter_utf8_post.html"
+ "POST parameter handling with UTF-8 charset")))
+ (:tr (:td (:a :href "/hunchentoot/test/redir.html"
+ "Redirect \(302) to info page above")))
+ (:tr (:td (:a :href "/hunchentoot/test/authorization.html"
+ "Authorization")
+ " (user 'nanook', password 'igloo')"))
+ (:tr (:td (:a :href "/hunchentoot/code/test.lisp"
+ "The source code of this test")))
+ (:tr (:td (:a :href "/hunchentoot/test/image.jpg"
+ "Binary data, delivered from file")
+ " \(a picture)"))
+ (:tr (:td (:a :href "/hunchentoot/test/image-ram.jpg"
+ "Binary data, delivered from RAM")
+ " \(same picture)"))
+ (:tr (:td (:a :href "/hunchentoot/test/easy-demo.html"
+ "\"Easy\" handler example")))
+ (:tr (:td (:a :href "/hunchentoot/test/utf8-binary.txt"
+ "UTF-8 demo")
+ " \(writing octets directly to the stream)"))
+ (:tr (:td (:a :href "/hunchentoot/test/utf8-character.txt"
+ "UTF-8 demo")
+ " \(writing UTF-8 characters directly to the stream)"))
+ (:tr (:td (:a :href "/hunchentoot/test/utf8-string.txt"
+ "UTF-8 demo")
+ " \(returning a string)"))
+ (:tr (:td (:a :href "/hunchentoot/test/upload.html"
+ "File uploads")))
+ (:tr (:td (:a :href "/hunchentoot/test/forbidden.html"
+ "Forbidden \(403) page")))
+ (:tr (:td (:a :href "/hunchentoot/test/oops.html"
+ "Error handling")
+ " \(output depends on settings like "
+ (:a :href "http://weitz.de/hunchentoot/#*show-lisp-errors-p*"
+ (:code "*SHOW-LISP-ERRORS-P*"))
+ (fmt " \(currently ~S) and " *show-lisp-errors-p*)
+ (:a :href "http://weitz.de/hunchentoot/#*show-lisp-backtraces-p*"
+ (:code "*SHOW-LISP-BACKTRACES-P*"))
+ (fmt " \(currently ~S)" *show-lisp-backtraces-p*)
+ ")"))
+ (:tr (:td (:a :href "/hunchentoot/foo"
+ "URI handled by")
+ " "
+ (:a :href "http://weitz.de/hunchentoot/#*default-handler*"
+ (:code "*DEFAULT-HANDLER*")))))))))
+
+(setq *dispatch-table*
+ (nconc
+ (list 'dispatch-easy-handlers
+ (create-static-file-dispatcher-and-handler
+ "/hunchentoot/test/image.jpg"
+ (make-pathname :name "fz" :type "jpg" :version nil
+ :defaults *this-file*)
+ "image/jpeg")
+ (create-static-file-dispatcher-and-handler
+ "/hunchentoot/test/favicon.ico"
+ (make-pathname :name "favicon" :type "ico" :version nil
+ :defaults *this-file*))
+ (create-folder-dispatcher-and-handler
+ "/hunchentoot/code/"
+ (make-pathname :name nil :type nil :version nil
+ :defaults *this-file*)
+ "text/plain"))
+ (mapcar (lambda (args)
+ (apply #'create-prefix-dispatcher args))
+ '(("/hunchentoot/test/form-test.html" form-test)
+ ("/hunchentoot/test/forbidden.html" forbidden)
+ ("/hunchentoot/test/info.html" info)
+ ("/hunchentoot/test/authorization.html" authorization-page)
+ ("/hunchentoot/test/image-ram.jpg" image-ram-page)
+ ("/hunchentoot/test/cookie.html" cookie-test)
+ ("/hunchentoot/test/session.html" session-test)
+ ("/hunchentoot/test/parameter_latin1_get.html" parameter-test-latin1-get)
+ ("/hunchentoot/test/parameter_latin1_post.html" parameter-test-latin1-post)
+ ("/hunchentoot/test/parameter_utf8_get.html" parameter-test-utf8-get)
+ ("/hunchentoot/test/parameter_utf8_post.html" parameter-test-utf8-post)
+ ("/hunchentoot/test/upload.html" upload-test)
+ ("/hunchentoot/test/redir.html" redir)
+ ("/hunchentoot/test/oops.html" oops)
+ ("/hunchentoot/test/utf8-binary.txt" stream-direct)
+ ("/hunchentoot/test/utf8-character.txt" stream-direct-utf-8)
+ ("/hunchentoot/test/utf8-string.txt" stream-direct-utf-8-string)
+ ("/hunchentoot/test/files/" send-file)
+ ("/hunchentoot/test" menu)))
+ (list #'default-dispatcher)))
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-acl.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-acl.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-acl.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,53 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/unix-acl.lisp,v 1.5 2007/01/01 23:50:30 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (require "osi"))
+
+(defun setuid (uid)
+ "Sets the effective user ID of the current process to UID - see
+setuid\(2)."
+ (excl.osi:setuid uid))
+
+(defun setgid (gid)
+ "Sets the effective group ID of the current process to GID -
+see setgid\(2)."
+ (excl.osi:setgid gid))
+
+(defun get-uid-from-name (name)
+ "Returns the UID for the user named NAME."
+ (excl.osi:pwent-uid (or (excl.osi:getpwnam name)
+ (error "User ~S not found." name))))
+
+(defun get-gid-from-name (name)
+ "Returns the GID for the group named NAME."
+ (excl.osi:grent-gid (or (excl.osi:getgrnam name)
+ (error "Group ~S not found." name))))
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-cmu.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-cmu.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-cmu.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,54 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/unix-cmu.lisp,v 1.5 2007/01/01 23:50:30 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(defun setuid (uid)
+ "Sets the effective user ID of the current process to UID - see
+setuid\(2)."
+ (multiple-value-bind (return-value errno)
+ (unix:unix-setuid uid)
+ (unless (and return-value (zerop return-value))
+ (error "setuid failed: ~A" (unix:get-unix-error-msg errno)))))
+
+(defun setgid (gid)
+ "Sets the effective group ID of the current process to GID -
+see setgid\(2)."
+ (multiple-value-bind (return-value errno)
+ (unix:unix-setgid gid)
+ (unless (and return-value (zerop return-value))
+ (error "setgid failed: ~A" (unix:get-unix-error-msg errno)))))
+
+(defun get-uid-from-name (name)
+ "Returns the UID for the user named NAME."
+ (unix:user-info-uid (unix:unix-getpwnam name)))
+
+(defun get-gid-from-name (name)
+ "Returns the GID for the group named NAME."
+ (unix:group-info-gid (unix:unix-getgrnam name)))
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-lw.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-lw.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-lw.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,93 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/unix-lw.lisp,v 1.4 2007/01/01 23:50:30 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(fli:define-foreign-function (%setuid "setuid")
+ ((uid :int))
+ :result-type :int)
+
+(defun setuid (uid)
+ "Sets the effective user ID of the current process to UID - see
+setuid\(2)."
+ (unless (zerop (%setuid uid))
+ (error "setuid failed: ~A" (lw:get-unix-error (lw:errno-value)))))
+
+(fli:define-foreign-function (%setgid "setgid")
+ ((gid :int))
+ :result-type :int)
+
+(defun setgid (gid)
+ "Sets the effective group ID of the current process to GID -
+see setgid\(2)."
+ (unless (zerop (%setgid gid))
+ (error "setgid failed: ~A" (lw:get-unix-error (lw:errno-value)))))
+
+(fli:define-c-struct passwd
+ (name (:pointer :char))
+ (passwd (:pointer :char))
+ (uid :int)
+ (gid :int)
+ (gecos (:pointer :char))
+ (dir (:pointer :char))
+ (shell (:pointer :char)))
+
+(fli:define-foreign-function (getpwnam "getpwnam")
+ ((name (:reference-pass :ef-mb-string)))
+ :result-type (:pointer passwd))
+
+(defun get-uid-from-name (name)
+ "Returns the UID for the user named NAME."
+ (let ((passwd (getpwnam name)))
+ (when (fli:null-pointer-p passwd)
+ (let ((errno (lw:errno-value)))
+ (cond ((zerop errno)
+ (error "User ~S not found." name))
+ (t (error "getpwnam failed: ~A" (lw:get-unix-error errno))))))
+ (fli:foreign-slot-value passwd 'uid)))
+
+(fli:define-c-struct group
+ (name (:pointer :char))
+ (passwd (:pointer :char))
+ (gid :int)
+ (mem (:pointer (:pointer :char))))
+
+(fli:define-foreign-function (getgrnam "getgrnam")
+ ((name (:reference-pass :ef-mb-string)))
+ :result-type (:pointer group))
+
+(defun get-gid-from-name (name)
+ "Returns the GID for the group named NAME."
+ (let ((group (getgrnam name)))
+ (when (fli:null-pointer-p group)
+ (let ((errno (lw:errno-value)))
+ (cond ((zerop errno)
+ (error "Group ~S not found." name))
+ (t (error "getgrnam failed: ~A" (lw:get-unix-error errno))))))
+ (fli:foreign-slot-value group 'gid)))
\ No newline at end of file
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-lw.lisp
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-mcl.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-mcl.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-mcl.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,54 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/unix-mcl.lisp,v 1.6 2007/01/01 23:50:30 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(defun setuid (uid)
+ "Sets the effective user ID of the current process to UID - see
+setuid\(2)."
+ (let ((errno (ccl::setuid uid)))
+ (unless (zerop errno)
+ (error "setuid failed with errno ~A." errno))))
+
+(defun setgid (gid)
+ "Sets the effective group ID of the current process to GID -
+see setgid\(2)."
+ (let ((errno (ccl::setgid gid)))
+ (unless (zerop errno)
+ (error "setgid failed with errno ~A." errno))))
+
+(defun get-uid-from-name (name)
+ "Returns the UID for the user named NAME."
+ (declare (ignore name))
+ (error "GET-UID-FROM-NAME not yet implemented for OpenMCL. Please send patches..."))
+
+(defun get-gid-from-name (name)
+ "Returns the GID for the group named NAME."
+ (declare (ignore name))
+ (error "GET-GID-FROM-NAME not yet implemented for OpenMCL. Please send patches..."))
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-sbcl.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-sbcl.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/unix-sbcl.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,57 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/unix-sbcl.lisp,v 1.7 2007/10/06 22:44:06 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (when (and (eq (nth-value 1 (find-symbol "GETGRNAM" :sb-posix)) :external)
+ (eq (nth-value 1 (find-symbol "GROUP-GID" :sb-posix)) :external))
+ (pushnew :sb-posix-has-getgrnam *features*)))
+
+(defun setuid (uid)
+ "Sets the effective user ID of the current process to UID - see
+setuid\(2)."
+ (sb-posix:setuid uid))
+
+(defun setgid (gid)
+ "Sets the effective group ID of the current process to GID -
+see setgid\(2)."
+ (sb-posix:setgid gid))
+
+(defun get-uid-from-name (name)
+ "Returns the UID for the user named NAME."
+ (sb-posix:passwd-uid (sb-posix:getpwnam name)))
+
+(defun get-gid-from-name (name)
+ "Returns the GID for the group named NAME."
+ (declare (ignorable name))
+ #+:sb-posix-has-getgrnam
+ (sb-posix:group-gid (sb-posix:getgrnam name))
+ #-:sb-posix-has-getgrnam
+ (error "You need a version of SBCL with SB-POSIX:GETGRNAM \(1.0.10.31 or higher)."))
Added: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/util.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/util.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/util.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -0,0 +1,406 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: HUNCHENTOOT; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/hunchentoot/util.lisp,v 1.32 2007/11/08 20:07:58 edi Exp $
+
+;;; Copyright (c) 2004-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :hunchentoot)
+
+#-:lispworks
+(defmacro when-let ((var form) &body body)
+ "Evaluates FORM and binds VAR to the result, then executes BODY
+if VAR has a true value."
+ `(let ((,var ,form))
+ (when ,var ,@body)))
+
+#-:lispworks
+(defmacro with-unique-names ((&rest bindings) &body body)
+ "Syntax: WITH-UNIQUE-NAMES ( { var | (var x) }* ) declaration* form*
+
+Executes a series of forms with each VAR bound to a fresh,
+uninterned symbol. The uninterned symbol is as if returned by a call
+to GENSYM with the string denoted by X - or, if X is not supplied, the
+string denoted by VAR - as argument.
+
+The variable bindings created are lexical unless special declarations
+are specified. The scopes of the name bindings and declarations do not
+include the Xs.
+
+The forms are evaluated in order, and the values of all but the last
+are discarded \(that is, the body is an implicit PROGN)."
+ ;; reference implementation posted to comp.lang.lisp as
+ ;; <cy3bshuf30f.fsf(a)ljosa.com> by Vebjorn Ljosa - see also
+ ;; <http://www.cliki.net/Common%20Lisp%20Utilities>
+ `(let ,(mapcar #'(lambda (binding)
+ (check-type binding (or cons symbol))
+ (if (consp binding)
+ (destructuring-bind (var x) binding
+ (check-type var symbol)
+ `(,var (gensym ,(etypecase x
+ (symbol (symbol-name x))
+ (character (string x))
+ (string x)))))
+ `(,binding (gensym ,(symbol-name binding)))))
+ bindings)
+ ,@body))
+
+#+:lispworks
+(defmacro with-rebinding (bindings &body body)
+ "Renaming LW:REBINDING for better indentation."
+ `(lw:rebinding ,bindings ,@body))
+
+#-:lispworks
+(defmacro with-rebinding (bindings &body body)
+ "Syntax: WITH-REBINDING ( { var | (var prefix) }* ) form*
+
+Evaluates a series of forms in the lexical environment that is
+formed by adding the binding of each VAR to a fresh, uninterned
+symbol, and the binding of that fresh, uninterned symbol to VAR's
+original value, i.e., its value in the current lexical environment.
+
+The uninterned symbol is created as if by a call to GENSYM with the
+string denoted by PREFIX - or, if PREFIX is not supplied, the string
+denoted by VAR - as argument.
+
+The forms are evaluated in order, and the values of all but the last
+are discarded \(that is, the body is an implicit PROGN)."
+ ;; reference implementation posted to comp.lang.lisp as
+ ;; <cy3wv0fya0p.fsf(a)ljosa.com> by Vebjorn Ljosa - see also
+ ;; <http://www.cliki.net/Common%20Lisp%20Utilities>
+ (loop for binding in bindings
+ for var = (if (consp binding) (car binding) binding)
+ for name = (gensym)
+ collect `(,name ,var) into renames
+ collect ``(,,var ,,name) into temps
+ finally (return `(let ,renames
+ (with-unique-names ,bindings
+ `(let (,,@temps)
+ ,,@body))))))
+
+(defun starts-with-p (seq subseq &key (test 'eql))
+ "Tests whether the sequence SEQ starts with the sequence
+SUBSEQ. Individual elements are compared with TEST."
+ (let* ((length (length subseq))
+ (mismatch (mismatch subseq seq
+ :test test)))
+ (or (null mismatch)
+ (<= length mismatch))))
+
+(defun starts-with-one-of-p (seq subseq-list &key (test 'eql))
+ "Tests whether the sequence SEQ starts with one of the
+sequences in SUBSEQ-LIST. Individual elements are compared with
+TEST."
+ (some (lambda (subseq)
+ (starts-with-p seq subseq :test test))
+ subseq-list))
+
+(defun create-random-string (&optional (n 10) (base 16))
+ "Returns a random number \(as a string) with base BASE and N
+digits."
+ (with-output-to-string (s)
+ (dotimes (i n)
+ (format s "~VR" base
+ (random base *the-random-state*)))))
+
+(defun reset-session-secret ()
+ "Sets *SESSION-SECRET* to a new random value. All old sessions will
+cease to be valid."
+ (setq *session-secret* (create-random-string 10 36)))
+
+(defun reason-phrase (return-code)
+ "Returns a reason phrase for the HTTP return code RETURN-CODE
+\(which should be an integer) or NIL for return codes Hunchentoot
+doesn't know."
+ (gethash return-code *http-reason-phrase-map*))
+
+(defun make-keyword (string &key (destructivep t))
+ "Interns the upcased version of STRING into the KEYWORD package.
+Uses NSTRING-UPCASE if DESTRUCTIVEP is true. Returns NIL if STRING is
+not a string."
+ (and (stringp string)
+ (intern (if destructivep
+ (nstring-upcase string)
+ (string-upcase string)) :keyword)))
+
+(defgeneric assoc (thing alist &key &allow-other-keys)
+ (:documentation "LIKE CL:ASSOC, but \'does the right thing\' if
+THING is a string or a symbol."))
+
+(defmethod assoc ((thing symbol) alist &key &allow-other-keys)
+ "Version of ASSOC for symbols, always uses EQ as test function."
+ (cl:assoc thing alist :test #'eq))
+
+(defmethod assoc ((thing string) alist &key (test #'string-equal))
+ "Version of ASSOC for strings, uses STRING-EQUAL as default test
+function."
+ (cl:assoc thing alist :test test))
+
+(defmethod assoc (thing alist &key (test #'eql))
+ "Default method - uses EQL as default test like CL:ASSOC."
+ (cl:assoc thing alist :test test))
+
+(defun md5-hex (string)
+ "Calculates the md5 sum of the string STRING and returns it as a hex string."
+ (with-output-to-string (s)
+ (loop for code across (md5:md5sum-sequence string)
+ do (format s "~2,'0x" code))))
+
+(defun escape-for-html (string)
+ "Escapes the characters #\\<, #\\>, #\\', #\\\", and #\\& for HTML output."
+ (with-output-to-string (out)
+ (with-input-from-string (in string)
+ (loop for char = (read-char in nil nil)
+ while char
+ do (case char
+ ((#\<) (write-string "<" out))
+ ((#\>) (write-string ">" out))
+ ((#\") (write-string """ out))
+ ((#\') (write-string "'" out))
+ ((#\&) (write-string "&" out))
+ (otherwise (write-char char out)))))))
+
+(defun http-token-p (token)
+ "Tests whether TOKEN is a string which is a valid 'token'
+according to HTTP/1.1 \(RFC 2068)."
+ (and (stringp token)
+ (plusp (length token))
+ (every (lambda (char)
+ (and ;; CHAR is US-ASCII but not control character or ESC
+ (< 31 (char-code char) 127)
+ ;; CHAR is not 'tspecial'
+ (not (find char "()<>@,;:\\\"/[]?={} " :test #'char=))))
+ token)))
+
+
+(defun rfc-1123-date (&optional (time (get-universal-time)))
+ "Generates a time string according to RFC 1123. Default is current time."
+ (multiple-value-bind
+ (second minute hour date month year day-of-week)
+ (decode-universal-time time 0)
+ (format nil "~A, ~2,'0d ~A ~4d ~2,'0d:~2,'0d:~2,'0d GMT"
+ (svref +day-names+ day-of-week)
+ date
+ (svref +month-names+ (1- month))
+ year
+ hour
+ minute
+ second)))
+
+(defun iso-time (&optional (time (get-universal-time)))
+ "Returns the universal time TIME as a string in full ISO format."
+ (multiple-value-bind (second minute hour date month year)
+ (decode-universal-time time)
+ (format nil "~4,'0d-~2,'0d-~2,'0d ~2,'0d:~2,'0d:~2,'0d"
+ year month date hour minute second)))
+
+(let ((counter 0))
+ (declare (ignorable counter))
+ (defun make-tmp-file-name (&optional (prefix "hunchentoot"))
+ "Generates a unique name for a temporary file. This function is
+called from the RFC2388 library when a file is uploaded."
+ (let ((tmp-file-name
+ #+:allegro
+ (pathname (system:make-temp-file-name prefix *tmp-directory*))
+ #-:allegro
+ (loop for pathname = (make-pathname :name (format nil "~A-~A"
+ prefix (incf counter))
+ :type nil
+ :defaults *tmp-directory*)
+ unless (probe-file pathname)
+ return pathname)))
+ (push tmp-file-name *tmp-files*)
+ ;; maybe call hook for file uploads
+ (when *file-upload-hook*
+ (funcall *file-upload-hook* tmp-file-name))
+ tmp-file-name)))
+
+(defun quote-string (string)
+ "Quotes string according to RFC 2616's definition of `quoted-string'."
+ (with-output-to-string (out)
+ (with-input-from-string (in string)
+ (loop for char = (read-char in nil nil)
+ while char
+ unless (or (char< char #\Space)
+ (char= char #\Rubout))
+ do (case char
+ ((#\\) (write-string "\\\\" out))
+ ((#\") (write-string "\\\"" out))
+ (otherwise (write-char char out)))))))
+
+(defun url-decode (string &optional (external-format *hunchentoot-default-external-format*))
+ "Decodes a URL-encoded STRING which is assumed to be encoded using
+the external format EXTERNAL-FORMAT."
+ (let ((vector (make-array (length string)
+ :element-type '(unsigned-byte 8)
+ :fill-pointer 0)))
+ (loop with percent-p and buff
+ for char of-type character across string
+ for i from 0
+ when buff do
+ (vector-push (parse-integer string
+ :start (1- i)
+ :end (1+ i)
+ :radix 16)
+ vector)
+ (setq buff nil)
+ else when percent-p
+ do (setq buff t
+ percent-p nil)
+ else when (char= char #\%)
+ do (setq percent-p t)
+ else do (vector-push (char-code (case char
+ ((#\+) #\Space)
+ (otherwise char)))
+ vector))
+ (octets-to-string vector :external-format external-format)))
+
+(defun form-url-encoded-list-to-alist (form-url-encoded-list
+ &optional (external-format *hunchentoot-default-external-format*))
+ "Converts a list FORM-URL-ENCODED-LIST of name/value pairs into an
+alist. Both names and values are url-decoded while doing this."
+ (mapcar #'(lambda (entry)
+ (destructuring-bind (name &optional value)
+ (split "=" entry :limit 2)
+ (cons (string-trim " " (url-decode name external-format))
+ (url-decode (or value "") external-format))))
+ form-url-encoded-list))
+
+(defun url-encode (string &optional (external-format *hunchentoot-default-external-format*))
+ "URL-encodes a string using the external format EXTERNAL-FORMAT."
+ (with-output-to-string (s)
+ (loop for c across string
+ for index from 0
+ do (cond ((or (char<= #\0 c #\9)
+ (char<= #\a c #\z)
+ (char<= #\A c #\Z)
+ ;; note that there's no comma in there - because of cookies
+ (find c "$-_.!*'()" :test #'char=))
+ (write-char c s))
+ (t (loop for octet across (string-to-octets string
+ :start index
+ :end (1+ index)
+ :external-format external-format)
+ do (format s "%~2,'0x" octet)))))))
+
+(defun force-output* (stream)
+ "Like FORCE-OUTPUT but aborts execution after
+*FORCE-OUTPUT-TIMEOUT* seconds."
+ (with-timeout (*force-output-timeout*
+ (warn "FORCE-OUTPUT didn't return after ~A seconds."
+ *force-output-timeout*))
+ (force-output stream)))
+
+(defun parse-content-type (content-type-header &optional want-external-format-p)
+ "Reads and parses a `Content-Type' header and returns it as three
+values - the type, the subtype, and an external format corresponding
+to the 'charset' parameter in the header \(or
+*HUNCHENTOOT-DEFAULT-EXTERNAL-FORMAT*), if there is one and if the
+content type is \"text\" or WANT-EXTERNAL-FORMAT-P is true.
+CONTENT-TYPE-HEADER is supposed to be the corresponding header value
+as a string."
+ (with-input-from-string (stream content-type-header)
+ (let* ((*current-error-message* "Corrupted Content-Type header:")
+ (type (read-token stream))
+ (subtype (and (or (ignore-errors (assert-char stream #\/))
+ (return-from parse-content-type
+ ;; try to return something meaningful
+ (values "application" "octet-stream"
+ (and want-external-format-p
+ *hunchentoot-default-external-format*))))
+ (read-token stream)))
+ (parameters (read-name-value-pairs stream))
+ (charset (cdr (assoc "charset" parameters)))
+ (external-format
+ (and (or want-external-format-p
+ (string-equal type "text"))
+ (or (when charset
+ (handler-case
+ (make-external-format (make-keyword charset) :eol-style :lf)
+ (error (condition)
+ (warn "Ignoring external format of name ~S~
+because of error:~%~A"
+ charset condition))))
+ *hunchentoot-default-external-format*))))
+ (values type subtype external-format))))
+
+(defun get-token-and-parameters (header)
+ (with-input-from-string (stream header)
+ (let* ((*current-error-message* (format nil "Corrupted header ~S:" header))
+ (token (read-token stream))
+ (parameters (read-name-value-pairs stream)))
+ (values token parameters))))
+
+(defun keep-alive-p ()
+ "Returns a true value unless the incoming request obviates a
+keep-alive reply. The second return value denotes whether the client
+has explicitly asked for a persistent connection."
+ (let ((connection-values
+ ;; the header might consist of different values separated by commas
+ (when-let (connection-header (header-in :connection))
+ (split "\\s*,\\s*" connection-header))))
+ (flet ((connection-value-p (value)
+ "Checks whether the string VALUE is one of the
+values of the `Connection' header."
+ (member value connection-values :test #'string-equal)))
+ (let ((keep-alive-requested-p (connection-value-p "keep-alive")))
+ (values (and (or (and (eq (server-protocol) :http/1.1)
+ (not (connection-value-p "close")))
+ (and (eq (server-protocol) :http/1.0)
+ keep-alive-requested-p)))
+ keep-alive-requested-p)))))
+
+(defun address-string ()
+ "Returns a string with information about Hunchentoot suitable for
+inclusion in HTML output."
+ (format nil "<address>~:[~3*~;<a href='http://httpd.apache.org/'>~A</a> / <a href='http://www.fractalconcept.com/asp/html/mod_lisp.html'>mod_lisp~A~@[/~A~]</a> / ~]<a href='http://weitz.de/hunchentoot/'>Hunchentoot ~A</a> <a href='~A'>(~A ~A)</a>~@[ at ~A~:[ (port ~D)~;~]~]</address>"
+ (server-mod-lisp-p *server*)
+ (or (header-in :server-baseversion) "Apache")
+ (or (header-in :modlisp-major-version) "")
+ (header-in :modlisp-version)
+ *hunchentoot-version*
+ +implementation-link+
+ (escape-for-html (lisp-implementation-type))
+ (escape-for-html (lisp-implementation-version))
+ (or (host *request*) (server-address *server*))
+ (scan ":\\d+$" (or (host *request*) ""))
+ (server-port)))
+
+(defun server-name-header ()
+ "Returns a string which can be used for 'Server' headers."
+ (format nil "Hunchentoot ~A" *hunchentoot-version*))
+
+(defun input-chunking-p ()
+ "Whether input chunking is currently switched on for \(the socket
+stream underlying) *HUNCHENTOOT-STREAM* - note that this will return
+NIL if the underlying stream of the flexi stream is not a chunked
+stream."
+ (chunked-stream-input-chunking-p (flexi-stream-stream *hunchentoot-stream*)))
+
+(defun cleanup-function ()
+ "The default for *CLEANUP-FUNCTION*. Invokes a GC on 32-bit
+LispWorks and does nothing on other Lisps."
+ #+(and :lispworks (not :lispworks-64bit))
+ (hcl:mark-and-sweep 2))
Property changes on: branches/trunk-reorg/thirdparty/hunchentoot-0.14.7/util.lisp
___________________________________________________________________
Name: svn:executable
+ *
Modified: branches/trunk-reorg/thirdparty/slime/CVS/Entries
===================================================================
--- branches/trunk-reorg/thirdparty/slime/CVS/Entries 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/slime/CVS/Entries 2007-11-15 07:42:51 UTC (rev 2282)
@@ -1,34 +1,35 @@
-/.cvsignore/1.5/Sun Apr 8 19:23:57 2007//
-/ChangeLog/1.1234/Thu Sep 27 12:56:13 2007//
-/HACKING/1.8/Wed Sep 19 11:08:27 2007//
-/NEWS/1.8/Sun Mar 27 19:41:17 2005//
-/PROBLEMS/1.8/Sun Nov 20 23:31:56 2005//
-/README/1.14/Tue Oct 3 21:49:13 2006//
-/hyperspec.el/1.11/Thu Dec 7 07:36:54 2006//
-/metering.lisp/1.4/Fri Apr 1 20:16:35 2005//
-/mkdist.sh/1.7/Mon Aug 29 20:02:58 2005//
-/nregex.lisp/1.4/Mon Sep 19 08:20:48 2005//
-/sbcl-pprint-patch.lisp/1.1/Fri Feb 17 01:30:21 2006//
-/slime-autoloads.el/1.3/Thu Sep 20 14:59:08 2007//
-/slime.el/1.875/Thu Sep 27 12:56:40 2007//
-/swank-abcl.lisp/1.43/Tue Sep 4 15:45:19 2007//
-/swank-allegro.lisp/1.98/Wed Sep 26 23:15:41 2007//
-/swank-backend.lisp/1.126/Mon Sep 10 15:39:05 2007//
-/swank-clisp.lisp/1.64/Thu Aug 23 19:03:37 2007//
-/swank-cmucl.lisp/1.174/Wed Sep 5 12:04:43 2007//
-/swank-corman.lisp/1.11/Thu Aug 23 19:03:37 2007//
-/swank-ecl.lisp/1.8/Thu May 17 11:49:40 2007//
-/swank-gray.lisp/1.10/Wed Apr 12 08:43:55 2006//
-/swank-lispworks.lisp/1.92/Thu Aug 23 19:03:37 2007//
-/swank-loader.lisp/1.73/Fri Sep 14 12:41:28 2007//
-/swank-openmcl.lisp/1.119/Thu Aug 23 19:03:37 2007//
-/swank-sbcl.lisp/1.185/Tue Sep 11 19:31:03 2007//
-/swank-scl.lisp/1.13/Thu Aug 23 19:03:37 2007//
-/swank-source-file-cache.lisp/1.8/Tue Dec 5 13:00:42 2006//
-/swank-source-path-parser.lisp/1.17/Sun Jun 25 08:33:16 2006//
-/swank.asd/1.5/Fri Sep 14 12:41:28 2007//
-/swank.lisp/1.511/Wed Sep 19 11:12:07 2007//
-/test-all.sh/1.2/Mon Aug 29 20:02:58 2005//
-/test.sh/1.9/Mon Aug 27 13:16:49 2007//
-/xref.lisp/1.2/Mon May 17 00:25:24 2004//
-D
+D/contrib////
+D/doc////
+/.cvsignore/1.5/Thu Oct 11 14:10:25 2007//
+/ChangeLog/1.1241/Wed Nov 14 21:30:35 2007//
+/HACKING/1.8/Thu Oct 11 14:10:25 2007//
+/NEWS/1.8/Thu Oct 11 14:10:25 2007//
+/PROBLEMS/1.8/Thu Oct 11 14:10:25 2007//
+/README/1.14/Thu Oct 11 14:10:25 2007//
+/hyperspec.el/1.11/Thu Oct 11 14:10:25 2007//
+/metering.lisp/1.4/Thu Oct 11 14:10:25 2007//
+/mkdist.sh/1.7/Thu Oct 11 14:10:25 2007//
+/nregex.lisp/1.4/Thu Oct 11 14:10:25 2007//
+/sbcl-pprint-patch.lisp/1.1/Thu Oct 11 14:10:25 2007//
+/slime-autoloads.el/1.3/Thu Oct 11 14:10:25 2007//
+/slime.el/1.877/Wed Nov 14 21:30:35 2007//
+/swank-abcl.lisp/1.44/Wed Nov 14 21:30:35 2007//
+/swank-allegro.lisp/1.98/Thu Oct 11 14:10:25 2007//
+/swank-backend.lisp/1.126/Thu Oct 11 14:10:25 2007//
+/swank-clisp.lisp/1.64/Thu Oct 11 14:10:25 2007//
+/swank-cmucl.lisp/1.174/Thu Oct 11 14:10:25 2007//
+/swank-corman.lisp/1.11/Thu Oct 11 14:10:25 2007//
+/swank-ecl.lisp/1.8/Thu Oct 11 14:10:25 2007//
+/swank-gray.lisp/1.10/Thu Oct 11 14:10:25 2007//
+/swank-lispworks.lisp/1.92/Thu Oct 11 14:10:25 2007//
+/swank-loader.lisp/1.74/Wed Nov 14 21:30:35 2007//
+/swank-openmcl.lisp/1.120/Wed Nov 14 21:30:35 2007//
+/swank-sbcl.lisp/1.185/Thu Oct 11 14:10:25 2007//
+/swank-scl.lisp/1.13/Thu Oct 11 14:10:25 2007//
+/swank-source-file-cache.lisp/1.8/Thu Oct 11 14:10:25 2007//
+/swank-source-path-parser.lisp/1.17/Thu Oct 11 14:10:25 2007//
+/swank.asd/1.5/Thu Oct 11 14:10:25 2007//
+/swank.lisp/1.513/Wed Nov 14 21:30:35 2007//
+/test-all.sh/1.2/Thu Oct 11 14:10:25 2007//
+/test.sh/1.9/Thu Oct 11 14:10:25 2007//
+/xref.lisp/1.2/Thu Oct 11 14:10:25 2007//
Modified: branches/trunk-reorg/thirdparty/slime/ChangeLog
===================================================================
--- branches/trunk-reorg/thirdparty/slime/ChangeLog 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/slime/ChangeLog 2007-11-15 07:42:51 UTC (rev 2282)
@@ -1,3 +1,67 @@
+2007-11-06 Helmut Eller <heller(a)common-lisp.net>
+
+ * slime.el (slime-events-buffer, slime-inspector-buffer): Disable
+ undo.
+
+2007-11-01 Tobias C. Rittweiler <tcr(a)freebits.de>
+
+ The inspector page layout has changed slightly. Before the header
+ looked like
+
+ A proper list.
+ [type: CONS]
+ -------------------
+
+ It now looks like
+
+ #<CONS {B3DBD39}>:
+ A proper list.
+ --------------------
+
+ Rationale is to have a "presentation link" to the currently
+ inspected object itself, to copy it down to the REPL via `M-RET'.
+ This is mostly useful when trying to get a value from the Slime
+ Debugger to the REPL, which you can do by inspecting the value
+ first by `i', and then using `M-RET' on the object representation
+ in the new header layout.
+
+ Such a "presentation link" existed already but was removed in
+ 2007-08-23. The old behaviour was to have the title ("A proper
+ list" in the above example) to contain the link. I decided to make
+ the link more explicit.
+
+ * swank.lisp (inspect-object): Now additionally returns a
+ string-representation of the object itself, and an inspector id
+ for it. Removed returning its type as this is implicit in the new
+ string representation.
+
+ * slime.el (slime-open-inspector): Adapted for new header layout.
+
+2007-10-22 Tobias C. Rittweiler <tcr(a)freebits.de>
+
+ * swank.lisp (read-softly-from-string, unintern-in-home-package):
+ Moved from `contrib/swank-arglist.lisp'.
+ (parse-package): Use them. (Removes FIXME about interning
+ symbols.) Also changed the logic somewhat to avoid passing :|| to
+ FIND-PACKAGE as ECL chokes on that.
+
+2007-10-22 Steve Smith <tarkasteve(a)gmail.com>
+
+ * swank-loader.lisp (compile-files-if-needed-serially): Added
+ missing `load' argument to function definition on Corman Lisp /
+ ECL.
+
+2007-10-22 Mark Evenson <mark.evenson(a)gmx.at>
+
+ * swank-abcl.lisp (getpid): Implemented.
+
+2007-10-22 R. Matthew Emerson <rme(a)thoughtstuff.com>
+
+ * swank-openmcl.lisp (closure-closed-over-values): Use
+ CCL::NTH-IMMEDIATE instead of CCL::%SVREF. This makes it work on
+ x86-64 OpenMCL. (The %SVREF worked on PPC, but this will work on
+ both.)
+
2007-09-27 Tobias C. Rittweiler <tcr(a)freebits.de>
* slime.el (slime-filesystem-toplevel-directory): New function.
Modified: branches/trunk-reorg/thirdparty/slime/contrib/CVS/Entries
===================================================================
--- branches/trunk-reorg/thirdparty/slime/contrib/CVS/Entries 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/slime/contrib/CVS/Entries 2007-11-15 07:42:51 UTC (rev 2282)
@@ -1,30 +1,30 @@
-/ChangeLog/1.62/Mon Oct 1 13:37:22 2007//
-/README/1.3/Fri Sep 28 13:05:44 2007//
-/bridge.el/1.1/Wed Sep 19 11:47:03 2007//
-/inferior-slime.el/1.2/Mon Sep 10 21:44:48 2007//
-/slime-asdf.el/1.3/Fri Sep 21 12:44:13 2007//
-/slime-autodoc.el/1.5/Mon Oct 1 13:37:10 2007//
-/slime-banner.el/1.4/Thu Sep 20 14:55:53 2007//
-/slime-c-p-c.el/1.8/Thu Sep 20 14:55:53 2007//
-/slime-editing-commands.el/1.5/Thu Sep 20 14:55:53 2007//
-/slime-fancy-inspector.el/1.2/Thu Sep 20 14:55:53 2007//
-/slime-fancy.el/1.4/Fri Sep 28 13:05:35 2007//
-/slime-fuzzy.el/1.4/Thu Sep 20 14:55:53 2007//
-/slime-highlight-edits.el/1.3/Thu Sep 20 14:55:53 2007//
-/slime-parse.el/1.7/Sat Sep 15 11:09:36 2007//
-/slime-presentation-streams.el/1.2/Tue Aug 28 08:25:12 2007//
-/slime-presentations.el/1.8/Thu Sep 20 14:55:53 2007//
-/slime-references.el/1.4/Thu Sep 20 14:55:53 2007//
-/slime-scratch.el/1.4/Thu Sep 20 14:55:53 2007//
-/slime-tramp.el/1.2/Tue Sep 4 10:18:44 2007//
-/slime-typeout-frame.el/1.5/Mon Oct 1 11:50:06 2007//
-/slime-xref-browser.el/1.1/Fri Aug 24 14:47:11 2007//
-/swank-arglists.lisp/1.10/Tue Sep 11 12:33:00 2007//
-/swank-asdf.lisp/1.1/Tue Sep 4 10:32:07 2007//
-/swank-c-p-c.lisp/1.2/Wed Sep 5 19:35:35 2007//
-/swank-fancy-inspector.lisp/1.4/Thu Sep 20 14:55:53 2007//
-/swank-fuzzy.lisp/1.6/Sat Sep 15 22:21:21 2007//
-/swank-listener-hooks.lisp/1.1/Tue Aug 28 13:53:02 2007//
-/swank-presentation-streams.lisp/1.4/Tue Aug 28 16:26:32 2007//
-/swank-presentations.lisp/1.4/Tue Sep 4 09:49:10 2007//
+/ChangeLog/1.64/Wed Nov 14 21:30:35 2007//
+/README/1.3/Thu Oct 11 14:10:25 2007//
+/bridge.el/1.1/Thu Oct 11 14:10:25 2007//
+/inferior-slime.el/1.2/Thu Oct 11 14:10:25 2007//
+/slime-asdf.el/1.3/Thu Oct 11 14:10:25 2007//
+/slime-autodoc.el/1.5/Thu Oct 11 14:10:25 2007//
+/slime-banner.el/1.4/Thu Oct 11 14:10:25 2007//
+/slime-c-p-c.el/1.8/Thu Oct 11 14:10:25 2007//
+/slime-editing-commands.el/1.5/Thu Oct 11 14:10:25 2007//
+/slime-fancy-inspector.el/1.2/Thu Oct 11 14:10:25 2007//
+/slime-fancy.el/1.4/Thu Oct 11 14:10:25 2007//
+/slime-fuzzy.el/1.4/Thu Oct 11 14:10:25 2007//
+/slime-highlight-edits.el/1.3/Thu Oct 11 14:10:25 2007//
+/slime-parse.el/1.7/Thu Oct 11 14:10:25 2007//
+/slime-presentation-streams.el/1.2/Thu Oct 11 14:10:25 2007//
+/slime-presentations.el/1.8/Thu Oct 11 14:10:25 2007//
+/slime-references.el/1.4/Thu Oct 11 14:10:25 2007//
+/slime-scratch.el/1.4/Thu Oct 11 14:10:25 2007//
+/slime-tramp.el/1.2/Thu Oct 11 14:10:25 2007//
+/slime-typeout-frame.el/1.5/Thu Oct 11 14:10:25 2007//
+/slime-xref-browser.el/1.1/Thu Oct 11 14:10:25 2007//
+/swank-arglists.lisp/1.12/Wed Nov 14 21:30:35 2007//
+/swank-asdf.lisp/1.1/Thu Oct 11 14:10:25 2007//
+/swank-c-p-c.lisp/1.2/Thu Oct 11 14:10:25 2007//
+/swank-fancy-inspector.lisp/1.4/Thu Oct 11 14:10:25 2007//
+/swank-fuzzy.lisp/1.6/Thu Oct 11 14:10:25 2007//
+/swank-listener-hooks.lisp/1.1/Thu Oct 11 14:10:25 2007//
+/swank-presentation-streams.lisp/1.4/Thu Oct 11 14:10:25 2007//
+/swank-presentations.lisp/1.4/Thu Oct 11 14:10:25 2007//
D
Modified: branches/trunk-reorg/thirdparty/slime/contrib/ChangeLog
===================================================================
--- branches/trunk-reorg/thirdparty/slime/contrib/ChangeLog 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/slime/contrib/ChangeLog 2007-11-15 07:42:51 UTC (rev 2282)
@@ -1,3 +1,15 @@
+2007-10-24 Tobias C. Rittweiler <tcr(a)freebits.de>
+
+ * swank-arglist.lisp (decode-arglist): Fix incompatibility with
+ ACL's modern reader mode. Thanks to Andreas Fuchs for stumbling
+ over this.
+
+2007-10-22 Tobias C. Rittweiler <tcr(a)freebits.de>
+
+ * swank-arglist.lisp (read-softly): Renamed to
+ READ-SOFTLY-FROM-STRING and moved to `swank.lisp'.
+ (unintern-in-home-package): Moved to `swank.lisp'.
+
2007-10-01 Tobias C. Rittweiler <tcr(a)freebits.de>
* slime-autdoc.el (slime-autodoc-message-ok-p): Don't display an
Modified: branches/trunk-reorg/thirdparty/slime/contrib/swank-arglists.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/slime/contrib/swank-arglists.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/slime/contrib/swank-arglists.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -199,8 +199,8 @@
the returned datum is a symbol and has been newly interned in
some package.
-If READER is not explicitly given, the function READ-SOFTLY is
-used instead."
+If READER is not explicitly given, the function
+READ-SOFTLY-FROM-STRING* is used instead."
(when spec
(with-buffer-syntax ()
(call-with-ignored-reader-errors
@@ -211,13 +211,13 @@
(etypecase element
(string
(multiple-value-bind (sexp newly-interned?)
- (funcall (or reader 'read-softly) element)
+ (funcall (or reader 'read-softly-from-string*) element)
(push sexp result)
(when newly-interned?
(push sexp newly-interned-symbols))))
(cons
(multiple-value-bind (read-spec interned-symbols)
- (read-form-spec element)
+ (read-form-spec element reader)
(push read-spec result)
(setf newly-interned-symbols
(append interned-symbols
@@ -227,29 +227,15 @@
(values (nreverse result)
(nreverse newly-interned-symbols))))))))
-(defun unintern-in-home-package (symbol)
- (unintern symbol (symbol-package symbol)))
+(defun read-softly-from-string* (string)
+ "Like READ-SOFTLY-FROM-STRING, but only returns the sexp and
+the flag if a symbol had to be interned."
+ (multiple-value-bind (sexp pos interned?)
+ (read-softly-from-string string)
+ (declare (ignore pos))
+ (values sexp interned?)))
-(defun read-softly (string)
- "Returns two values:
- 1. the object resulting from READing STRING.
-
- 2. T if the object is a symbol that had to be newly interned
- in some package. (This does not work for symbols in
- compound forms like lists or vectors.)"
- (multiple-value-bind (symbol found? symbol-name package) (parse-symbol string)
- (if found?
- (values symbol nil)
- (let ((sexp (read-from-string string)))
- (values sexp
- (when (symbolp sexp)
- (prog1 t
- ;; assert that PARSE-SYMBOL didn't parse incorrectly.
- (assert (and (equal symbol-name (symbol-name sexp))
- (eq package (symbol-package sexp)))))))))))
-
-
(defstruct (arglist (:conc-name arglist.) (:predicate arglist-p))
provided-args ; list of the provided actual arguments
required-args ; list of the required arguments
@@ -541,7 +527,7 @@
(setq mode arg)
(push arg (arglist.known-junk result)))
((and (symbolp arg)
- (string= (symbol-name arg) (string '#:&ANY))) ; may be interned
+ (string= (symbol-name arg) (string '#:&any))) ; may be interned
(setf (arglist.any-p result) t) ; in any *package*.
(setq mode '&any))
((member arg lambda-list-keywords)
Modified: branches/trunk-reorg/thirdparty/slime/doc/CVS/Entries
===================================================================
--- branches/trunk-reorg/thirdparty/slime/doc/CVS/Entries 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/slime/doc/CVS/Entries 2007-11-15 07:42:51 UTC (rev 2282)
@@ -1,9 +1,9 @@
-/.cvsignore/1.1/Mon Jul 24 14:13:23 2006//
-/Makefile/1.12/Mon Sep 17 14:04:27 2007//
-/slime-refcard.pdf/1.1/Thu Aug 9 09:18:50 2007//
-/slime-refcard.tex/1.1/Thu Aug 9 09:18:50 2007//
-/slime-small.eps/1.1/Wed Nov 22 06:27:38 2006//
-/slime-small.pdf/1.1/Wed Nov 22 06:27:38 2006//
-/slime.texi/1.57/Mon Sep 17 13:44:48 2007//
-/texinfo-tabulate.awk/1.2/Mon Aug 29 20:02:57 2005//
+/.cvsignore/1.1/Thu Oct 11 14:10:24 2007//
+/Makefile/1.12/Thu Oct 11 14:10:24 2007//
+/slime-refcard.pdf/1.1/Thu Oct 11 14:10:24 2007//
+/slime-refcard.tex/1.1/Thu Oct 11 14:10:24 2007//
+/slime-small.eps/1.1/Thu Oct 11 14:10:24 2007//
+/slime-small.pdf/1.1/Thu Oct 11 14:10:24 2007//
+/slime.texi/1.57/Thu Oct 11 14:10:24 2007//
+/texinfo-tabulate.awk/1.2/Thu Oct 11 14:10:24 2007//
D
Modified: branches/trunk-reorg/thirdparty/slime/slime.el
===================================================================
--- branches/trunk-reorg/thirdparty/slime/slime.el 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/slime/slime.el 2007-11-15 07:42:51 UTC (rev 2282)
@@ -2486,6 +2486,7 @@
(or (get-buffer slime-event-buffer-name)
(let ((buffer (get-buffer-create slime-event-buffer-name)))
(with-current-buffer buffer
+ (buffer-disable-undo)
(set (make-local-variable 'outline-regexp) "^(")
(set (make-local-variable 'comment-start) ";")
(set (make-local-variable 'comment-end) "")
@@ -7470,6 +7471,7 @@
(or (get-buffer "*Slime Inspector*")
(with-current-buffer (get-buffer-create "*Slime Inspector*")
(setq slime-inspector-mark-stack '())
+ (buffer-disable-undo)
(slime-mode t)
(slime-inspector-mode)
(make-local-variable 'slime-saved-window-config)
@@ -7486,14 +7488,19 @@
(setq slime-buffer-connection (slime-current-connection))
(let ((inhibit-read-only t))
(erase-buffer)
- (destructuring-bind (&key title type content) inspected-parts
+ (destructuring-bind (&key string-representation id title content) inspected-parts
(macrolet ((fontify (face string)
`(slime-inspector-fontify ,face ,string)))
+ (slime-propertize-region
+ (list 'slime-part-number id
+ 'mouse-face 'highlight
+ 'face 'slime-inspector-value-face)
+ (insert string-representation))
+ (insert ":\n ")
(insert (fontify topline title))
(while (eq (char-before) ?\n)
(backward-delete-char 1))
- (insert "\n [" (fontify label "type:") " " (fontify type type) "]\n"
- (fontify label "--------------------") "\n")
+ (insert "\n" (fontify label "--------------------") "\n")
(save-excursion
(mapc #'slime-inspector-insert-ispec content))
(pop-to-buffer (current-buffer))
Modified: branches/trunk-reorg/thirdparty/slime/swank-abcl.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/slime/swank-abcl.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/slime/swank-abcl.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -142,9 +142,39 @@
(defimplementation call-without-interrupts (fn)
(funcall fn))
-;;there are too many to count
(defimplementation getpid ()
- 0)
+ (if (not (find :unix *features*))
+ 0
+ (let* ((runtime
+ (java:jstatic "getRuntime" "java.lang.Runtime"))
+ (command
+ (java:jnew-array-from-array
+ "java.lang.String" #("sh" "-c" "echo $PPID")))
+ (runtime-exec-jmethod
+ ;; Complicated because java.lang.Runtime.exec() is
+ ;; overloaded on a non-primitive type (array of
+ ;; java.lang.String), so we have to use the actual parameter
+ ;; instance to get java.lang.Class
+ (java:jmethod "java.lang.Runtime" "exec"
+ (java:jcall
+ (java:jmethod "java.lang.Object" "getClass")
+ command)))
+ (process
+ (java:jcall runtime-exec-jmethod runtime command))
+ (output
+ (java:jcall (java:jmethod "java.lang.Process" "getInputStream")
+ process)))
+ (java:jcall (java:jmethod "java.lang.Process" "waitFor") process)
+ (loop
+ :with b
+ :do (setq b
+ (java:jcall (java:jmethod "java.io.InputStream" "read")
+ output))
+ :until (member b '(-1 #x0a)) ; Either EOF or LF
+ :collecting (code-char b) :into result
+ :finally (return
+ (values
+ (parse-integer (coerce result 'string))))))))
(defimplementation lisp-implementation-type-name ()
"armedbear")
Modified: branches/trunk-reorg/thirdparty/slime/swank-loader.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/slime/swank-loader.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/slime/swank-loader.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -166,12 +166,13 @@
(handle-loadtime-error c binary-pathname)))))))
#+(or cormanlisp ecl)
-(defun compile-files-if-needed-serially (files fasl-directory)
+(defun compile-files-if-needed-serially (files fasl-directory load)
"Corman Lisp and ECL have trouble with compiled files."
(declare (ignore fasl-directory))
- (dolist (file files)
- (load file :verbose t)
- (force-output)))
+ (when load
+ (dolist (file files)
+ (load file :verbose t)
+ (force-output))))
(defun load-user-init-file ()
"Load the user init file, return NIL if it does not exist."
Modified: branches/trunk-reorg/thirdparty/slime/swank-openmcl.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/slime/swank-openmcl.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/slime/swank-openmcl.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -849,7 +849,7 @@
(let ((howmany (nth-value 8 (ccl::function-args (ccl::closure-function closure)))))
(loop for n below howmany
collect
- (let* ((value (ccl::%svref closure (+ 1 (- howmany n))))
+ (let* ((value (ccl::nth-immediate closure (+ 1 (- howmany n))))
(map (car (ccl::function-symbol-map (ccl::closure-function closure))))
(label (or (and map (svref map n)) n))
(cellp (ccl::closed-over-value-p value)))
Modified: branches/trunk-reorg/thirdparty/slime/swank.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/slime/swank.lisp 2007-11-14 15:28:13 UTC (rev 2281)
+++ branches/trunk-reorg/thirdparty/slime/swank.lisp 2007-11-15 07:42:51 UTC (rev 2282)
@@ -1517,6 +1517,30 @@
(let ((*read-suppress* nil))
(read-from-string string))))
+(defun read-softly-from-string (string)
+ "Returns three values:
+
+ 1. the object resulting from READing STRING.
+
+ 2. The index of the first character in STRING that was not read.
+
+ 3. T if the object is a symbol that had to be newly interned
+ in some package. (This does not work for symbols in
+ compound forms like lists or vectors.)"
+ (multiple-value-bind (symbol found? symbol-name package) (parse-symbol string)
+ (if found?
+ (values symbol nil)
+ (multiple-value-bind (sexp pos) (read-from-string string)
+ (values sexp pos
+ (when (symbolp sexp)
+ (prog1 t
+ ;; assert that PARSE-SYMBOL didn't parse incorrectly.
+ (assert (and (equal symbol-name (symbol-name sexp))
+ (eq package (symbol-package sexp)))))))))))
+
+(defun unintern-in-home-package (symbol)
+ (unintern symbol (symbol-package symbol)))
+
;; FIXME: deal with #\| etc. hard to do portably.
(defun tokenize-symbol (string)
"STRING is interpreted as the string representation of a symbol
@@ -1602,20 +1626,23 @@
(values symbol status)
(error "Unknown symbol: ~A [in ~A]" string package))))
-;; FIXME: interns the name
(defun parse-package (string)
"Find the package named STRING.
Return the package or nil."
- (multiple-value-bind (name pos)
- (if (zerop (length string))
- (values :|| 0)
+ (check-type string (or string null))
+ (if (zerop (length string))
+ nil
+ (multiple-value-bind (name pos interned?)
(let ((*package* *swank-io-package*))
- (ignore-errors (read-from-string string))))
- (and name
- (or (symbolp name)
- (stringp name))
- (= (length string) pos)
- (find-package name))))
+ (ignore-errors (read-softly-from-string string)))
+ (unwind-protect
+ (and name
+ (or (symbolp name)
+ (stringp name))
+ (= (length string) pos)
+ (find-package name))
+ (when interned?
+ (unintern-in-home-package name))))))
(defun unparse-name (string)
"Print the name STRING according to the current printer settings."
@@ -2907,7 +2934,10 @@
(*print-readably* nil))
(multiple-value-bind (title content) (inspect-for-emacs object inspector)
(list :title title
- :type (to-string (type-of object))
+ :string-representation
+ (with-output-to-string (stream)
+ (print-unreadable-object (object stream :type t :identity t)))
+ :id (assign-index object *inspectee-parts*)
:content (inspector-content-for-emacs content)))))
(defslimefun inspector-nth-part (index)
1
0

14 Nov '07
Author: hhubner
Date: 2007-11-14 10:28:13 -0500 (Wed, 14 Nov 2007)
New Revision: 2281
Modified:
branches/trunk-reorg/bknr/datastore/src/data/txn.lisp
Log:
Revive accidentially removed lines.
Modified: branches/trunk-reorg/bknr/datastore/src/data/txn.lisp
===================================================================
--- branches/trunk-reorg/bknr/datastore/src/data/txn.lisp 2007-11-14 07:35:39 UTC (rev 2280)
+++ branches/trunk-reorg/bknr/datastore/src/data/txn.lisp 2007-11-14 15:28:13 UTC (rev 2281)
@@ -137,14 +137,16 @@
(with-open-file (f (store-random-state-pathname store))
(format t "reading store random state~%")
(setf (store-random-state store) (read f)))
- (with-open-file (f (store-random-state-pathname store) :direction :output :if-does-not-exist :create)
+ (with-open-file (f (store-random-state-pathname store)
+ :direction :output :if-does-not-exist :create :if-exists :supersede)
(format t "initializing store random state~%")
(with-standard-io-syntax
(prin1 (setf (store-random-state store) (make-random-state t)) f)))))
(defmethod update-store-random-state ((store store))
(format t "saving store random state~%")
- (with-open-file (f (store-random-state-pathname store) :direction :output :if-does-not-exist :create)
+ (with-open-file (f (store-random-state-pathname store)
+ :direction :output :if-does-not-exist :create :if-exists :supersede)
(with-standard-io-syntax
(prin1 (store-random-state store) f))))
@@ -478,10 +480,11 @@
(format *trace-output* "Snapshotting subsystem ~A of ~A~%" subsystem store))
(snapshot-subsystem store subsystem)
(when *store-debug*
- (format *trace-output* "Successfully snapshotted ~A of ~A~%" subsystem store))))
+ (format *trace-output* "Successfully snapshotted ~A of ~A~%" subsystem store)))
+ (setf (store-transaction-run-time store) 0)
+ (setf error nil))
(when error
- (warn "Restoring backup ~A to current."
- backup-directory)
+ (warn "Restoring backup ~A to current." backup-directory)
(rename-file backup-directory (store-current-directory store))))))))))
(defvar *show-transactions* nil)
1
0

14 Nov '07
Author: hhubner
Date: 2007-11-14 02:35:39 -0500 (Wed, 14 Nov 2007)
New Revision: 2280
Modified:
branches/trunk-reorg/projects/scrabble/src/start-webserver.lisp
Log:
Remove hunchentoot patch.
Modified: branches/trunk-reorg/projects/scrabble/src/start-webserver.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/start-webserver.lisp 2007-11-14 07:31:01 UTC (rev 2279)
+++ branches/trunk-reorg/projects/scrabble/src/start-webserver.lisp 2007-11-14 07:35:39 UTC (rev 2280)
@@ -20,45 +20,6 @@
(make-pathname :name nil :type nil :version nil
:defaults (merge-pathnames #p"../../../thirdparty/MochiKit/MochiKit/" *load-truename*)))
-
-;; for now...
-(in-package :hunchentoot)
-
-(defun enough-url (url url-prefix)
- (subseq url (mismatch url url-prefix)))
-
-(defun create-folder-dispatcher-and-handler (uri-prefix base-path &optional content-type)
- "Creates and returns a dispatch function which will dispatch to a
-handler function which emits the file relative to BASE-PATH that is
-denoted by the URI of the request relative to URI-PREFIX. URI-PREFIX
-must be a string ending with a slash, BASE-PATH must be a pathname
-designator for an existing directory. If CONTENT-TYPE is not NIL,
-it'll be the content type used for all files in the folder."
- (unless (and (stringp uri-prefix)
- (plusp (length uri-prefix))
- (char= (char uri-prefix (1- (length uri-prefix))) #\/))
- (error "~S must be string ending with a slash." uri-prefix))
- (when (or (pathname-name base-path)
- (pathname-type base-path))
- (error "~S is supposed to denote a directory." base-path))
- (flet ((handler ()
- (let* ((script-name (url-decode (script-name)))
- (script-path (enough-url (regex-replace-all "\\\\" script-name "/")
- uri-prefix))
- (script-path-directory (pathname-directory script-path)))
- (unless (or (stringp script-path-directory)
- (null script-path-directory)
- (and (listp script-path-directory)
- (eq (first script-path-directory) :relative)
- (loop for component in (rest script-path-directory)
- always (stringp component))))
- (setf (return-code) +http-forbidden+)
- (throw 'handler-done nil))
- (handle-static-file (merge-pathnames script-path base-path) content-type))))
- (create-prefix-dispatcher uri-prefix #'handler)))
-
-(in-package :scrabble.web)
-
(defun start-webserver (&key (port 4242))
(open-scrabble-store)
(when (and (boundp '*server*) *server*)
1
0

14 Nov '07
Author: hhubner
Date: 2007-11-14 02:31:01 -0500 (Wed, 14 Nov 2007)
New Revision: 2279
Modified:
branches/trunk-reorg/thirdparty/hunchentoot-0.14.6/misc.lisp
Log:
Fix for OpenMCL, ENOUGH-NAMESTRING should be used only for path names,
not URIs.
Modified: branches/trunk-reorg/thirdparty/hunchentoot-0.14.6/misc.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/hunchentoot-0.14.6/misc.lisp 2007-11-14 07:13:33 UTC (rev 2278)
+++ branches/trunk-reorg/thirdparty/hunchentoot-0.14.6/misc.lisp 2007-11-14 07:31:01 UTC (rev 2279)
@@ -177,6 +177,9 @@
(lambda ()
(handle-static-file path content-type)))))
+(defun enough-url (url url-prefix)
+ (subseq url (mismatch url url-prefix)))
+
(defun create-folder-dispatcher-and-handler (uri-prefix base-path &optional content-type)
"Creates and returns a dispatch function which will dispatch to a
handler function which emits the file relative to BASE-PATH that is
@@ -193,8 +196,8 @@
(error "~S is supposed to denote a directory." base-path))
(flet ((handler ()
(let* ((script-name (url-decode (script-name)))
- (script-path (enough-namestring (regex-replace-all "\\\\" script-name "/")
- uri-prefix))
+ (script-path (enough-url (regex-replace-all "\\\\" script-name "/")
+ uri-prefix))
(script-path-directory (pathname-directory script-path)))
(unless (or (stringp script-path-directory)
(null script-path-directory)
1
0

14 Nov '07
Author: hhubner
Date: 2007-11-14 02:13:33 -0500 (Wed, 14 Nov 2007)
New Revision: 2278
Modified:
branches/trunk-reorg/bknr/datastore/src/data/txn.lisp
Log:
Add :SHARING :LOCK to transaction log stream open args so that it can
be used by multiple threads.
Modified: branches/trunk-reorg/bknr/datastore/src/data/txn.lisp
===================================================================
--- branches/trunk-reorg/bknr/datastore/src/data/txn.lisp 2007-11-14 07:00:51 UTC (rev 2277)
+++ branches/trunk-reorg/bknr/datastore/src/data/txn.lisp 2007-11-14 07:13:33 UTC (rev 2278)
@@ -177,7 +177,8 @@
:element-type '(unsigned-byte 8)
:direction :output
:if-does-not-exist :create
- :if-exists :append)))))
+ :if-exists :append
+ #+openmcl :sharing #+openmcl :lock)))))
(defmethod close-transaction-log-stream ((store store))
(with-slots (transaction-log-stream) store
1
0

14 Nov '07
Author: hhubner
Date: 2007-11-14 02:00:51 -0500 (Wed, 14 Nov 2007)
New Revision: 2277
Modified:
branches/trunk-reorg/projects/scrabble/src/package.lisp
Log:
Add required exports
Modified: branches/trunk-reorg/projects/scrabble/src/package.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/package.lisp 2007-11-14 05:27:46 UTC (rev 2276)
+++ branches/trunk-reorg/projects/scrabble/src/package.lisp 2007-11-14 07:00:51 UTC (rev 2277)
@@ -33,12 +33,16 @@
"TILE-OF"
"MAKE-MOVE"
+
"MOVE"
"SCORE-OF"
"PARTICIPANT-OF"
"WORDS-FORMED-OF"
"PLACED-TILES-OF"
+ "MOVE-WITHDRAWAL"
+ "REASON-OF"
+
"GAME"
"LANGUAGE-OF"
"PARTICIPANTS-OF"
1
0

[bknr-cvs] r2276 - in branches/trunk-reorg/projects/scrabble: src website
by bknr@bknr.net 14 Nov '07
by bknr@bknr.net 14 Nov '07
14 Nov '07
Author: hhubner
Date: 2007-11-14 00:27:46 -0500 (Wed, 14 Nov 2007)
New Revision: 2276
Modified:
branches/trunk-reorg/projects/scrabble/src/game.lisp
branches/trunk-reorg/projects/scrabble/src/package.lisp
branches/trunk-reorg/projects/scrabble/src/rules.lisp
branches/trunk-reorg/projects/scrabble/src/start-webserver.lisp
branches/trunk-reorg/projects/scrabble/src/web.lisp
branches/trunk-reorg/projects/scrabble/website/scrabble.html
branches/trunk-reorg/projects/scrabble/website/scrabble.js
Log:
snapshot
Modified: branches/trunk-reorg/projects/scrabble/src/game.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/game.lisp 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/src/game.lisp 2007-11-14 05:27:46 UTC (rev 2276)
@@ -17,12 +17,10 @@
(let ((tmp (aref tiles i))
(random-index (random (fill-pointer tiles))))
(setf (aref tiles i) (aref tiles random-index))
- (setf (aref tiles random-index) tmp)))))
+ (setf (aref tiles random-index) tmp))))
+ tile-bag)
-(defmethod initialize-persistent-instance :after ((tile-bag tile-bag))
- (shake-tile-bag tile-bag))
-
-(defun make-tile-bag (language)
+(deftransaction make-tile-bag (language)
(let ((tiles (make-array 102 :adjustable t :fill-pointer 0)))
(mapcar (lambda (entry)
(destructuring-bind (letter value count) entry
@@ -30,7 +28,7 @@
(vector-push-extend (make-tile letter value) tiles))))
(or (getf *tile-sets* language)
(error "language ~A not defined" language)))
- (make-object 'tile-bag :tiles tiles)))
+ (shake-tile-bag (make-object 'tile-bag :tiles tiles))))
(define-condition no-tiles-remaining (simple-error)
())
@@ -76,8 +74,8 @@
((participant :initarg :participant
:reader participant-of)
(placed-tiles :initarg :placed-tiles
- :reader placed-tiles)
- (new-tiles-drawn :initarg :new-letters-drawn
+ :reader placed-tiles-of)
+ (new-tiles-drawn :initarg :new-tiles-drawn
:reader new-tiles-drawn-of
:documentation "New letters that have been drawn after
the move, should the move need to be undone")
@@ -91,7 +89,7 @@
(print-unreadable-object (move stream :type t)
(format stream "by ~A, ~A points (~{~A~^, ~})"
(player-of (participant-of move))
- (reduce #'+ (mapcar #'cdr (words-formed-of move)))
+ (score-of move)
(words-formed-of move))))
(defclass game (store-object)
@@ -159,14 +157,13 @@
(let ((tray-letters (mapcar #'letter-of (tray-of participant)))
(placed-letters (mapcar (compose #'letter-of #'tile-of) placed-tiles)))
(dolist (letter placed-letters)
- (let ((has-letter (find letter tray-letters :test #'letter-equal))
- (has-blank (find nil tray-letters)))
- (unless (or has-letter has-blank)
- (error "participant ~A does not have tile ~A" participant letter))
- (setf tray-letters
- (if has-letter
- (remove letter tray-letters :test #'letter-equal :count 1)
- (remove nil tray-letters :key #'letter-of :count 1)))))))
+ (let ((has-letter (find letter tray-letters :test #'letter-equal)))
+ (unless (or has-letter (find nil tray-letters))
+ (error "participant ~A does not have tile ~A" participant letter))
+ (setf tray-letters
+ (if has-letter
+ (remove letter tray-letters :test #'letter-equal :count 1)
+ (remove nil tray-letters :key #'letter-of :count 1)))))))
(defun remove-letters-from-participant-tray (participant tiles)
(let (removed-tiles)
@@ -182,30 +179,35 @@
(append drawn (tray-of participant)))
drawn))
+(deftransaction make-move% (game participant placed-tiles)
+ (let ((words-formed (mapcar (lambda (word-result)
+ (cons (word-text word-result) (word-score word-result)))
+ (words-formed (board-of game) placed-tiles))))
+ (dolist (placed-tile placed-tiles)
+ (put-letter (board-of game) (tile-of placed-tile) (x-of placed-tile) (y-of placed-tile)))
+ (let ((tiles-used (remove-letters-from-participant-tray participant (mapcar #'tile-of placed-tiles)))
+ (tiles-drawn (draw-new-letters (tile-bag-of game) participant (length placed-tiles)))
+ (score (reduce #'+ (mapcar #'cdr words-formed))))
+ (when (eql 7 (length tiles-used))
+ (incf score 50))
+ (incf (score-of participant) score)
+ (let ((move (make-object 'move
+ :participant participant
+ :placed-tiles placed-tiles
+ :new-tiles-drawn tiles-drawn
+ :words-formed words-formed
+ :score score)))
+ (push move (moves-of game))
+ (rotate-participants game)
+ move))))
+
(defun make-move (game participant placed-tiles)
(ensure-participants-turn game participant)
(ensure-participant-has-tiles participant placed-tiles)
(check-move-legality (board-of game) placed-tiles)
- (with-transaction (:make-move)
- (let ((words-formed (mapcar (lambda (word-result)
- (cons (word-text word-result) (word-score word-result)))
- (words-formed (board-of game) placed-tiles))))
- (dolist (placed-tile placed-tiles)
- (put-letter (board-of game) (tile-of placed-tile) (x-of placed-tile) (y-of placed-tile)))
- (let ((tiles-used (remove-letters-from-participant-tray participant (mapcar #'tile-of placed-tiles)))
- (tiles-drawn (draw-new-letters (tile-bag-of game) participant (length placed-tiles)))
- (score (reduce #'+ (mapcar #'cdr words-formed))))
- (when (= 7 (length tiles-used))
- (incf score 50))
- (incf (score-of participant) score)
- (push (make-object 'move
- :participant participant
- :placed-tiles placed-tiles
- :new-tiles-drawn tiles-drawn
- :words-formed words-formed
- :score score)
- (moves-of game))))
- (rotate-participants game)))
+ (make-move% game participant (mapcar (lambda (placement)
+ (list (x-of placement) (y-of placement) (tile-of placement)))
+ placed-tiles)))
(defclass move-withdrawal (store-object)
((participant :initarg :participant
@@ -214,26 +216,28 @@
:reader reason-of))
(:metaclass persistent-class))
+(deftransaction withdraw-last-move% (game reason move)
+ (with-slots (participant placed-tiles new-tiles-drawn score) move
+ (decf (score-of participant) score)
+ (setf (tray-of participant)
+ (append (set-difference (tray-of participant) new-tiles-drawn)
+ (mapcar #'tile-of placed-tiles)))
+ (undraw-tiles (tile-bag-of game) new-tiles-drawn)
+ (dolist (placement placed-tiles)
+ (put-letter (board-of game) nil (x-of placement) (y-of placement)))
+ (unrotate-participants game)
+ (push (make-object 'move-withdrawal
+ :participant participant
+ :reason reason)
+ (moves-of game))))
+
(defun withdraw-last-move (game reason)
(let ((move (car (moves-of game))))
(unless move
(error "no move in game to withdraw"))
- (unless (typep game 'move)
+ (unless (typep move 'move)
(error "last move was not a letter placement, can't be withdrawn"))
- (with-transaction (:withdraw-last-move)
- (with-slots (participant placed-tiles new-tiles-drawn score) move
- (decf (score-of participant) score)
- (setf (tiles-of (tray-of participant))
- (append (set-difference (tiles-of (tray-of participant))
- new-tiles-drawn)
- (mapcar #'tile-of placed-tiles)))
- (undraw-tiles (tile-bag-of game) new-tiles-drawn)
- (dolist (placement placed-tiles)
- (put-letter (board-of game) nil (x-of placement) (y-of placement)))
- (push (make-object 'move-withdrawal
- :participant participant
- :reason reason)
- (moves-of game))))))
+ (withdraw-last-move% game reason move)))
(defclass tile-swap (store-object)
((participant :initarg :participant
@@ -247,8 +251,7 @@
(error "not enough remaining tiles to swap"))
(with-transaction (:swap-tiles)
(setf (tray-of participant)
- (append (set-difference (tray-of participant)
- tiles)
+ (append (set-difference (tray-of participant) tiles)
(draw-tiles (tile-bag-of game) (length tiles))))
(undraw-tiles (tile-bag-of game) tiles)
(push (make-object 'tile-swap
Modified: branches/trunk-reorg/projects/scrabble/src/package.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/package.lisp 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/src/package.lisp 2007-11-14 05:27:46 UTC (rev 2276)
@@ -28,11 +28,16 @@
"TRAY-OF"
"MAKE-TILE-PLACEMENTS"
+ "X-OF"
+ "Y-OF"
+ "TILE-OF"
+
"MAKE-MOVE"
"MOVE"
"SCORE-OF"
"PARTICIPANT-OF"
"WORDS-FORMED-OF"
+ "PLACED-TILES-OF"
"GAME"
"LANGUAGE-OF"
Modified: branches/trunk-reorg/projects/scrabble/src/rules.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/rules.lisp 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/src/rules.lisp 2007-11-14 05:27:46 UTC (rev 2276)
@@ -41,7 +41,7 @@
(and (= (x-of tile-placement-1) (x-of tile-placement-2))
(= (y-of tile-placement-1) (y-of tile-placement-2))))
-(defmethod position-equal ((position list) (tile-placement tile-placement))
+(defmethod position-equal ((position list) tile-placement)
"Return non-nil if the given POSITION is at the position of PLACED-TILE"
(and (= (first position) (x-of tile-placement))
(= (second position) (y-of tile-placement))))
@@ -63,14 +63,13 @@
(format stream "~C " (aif (at-xy board x y) (letter-of it) #\.)))
(terpri stream))))
-
(defmethod at-xy ((board board) x y)
(aref (placed-tiles-of board) x y))
(defmethod at-placement ((board board) tile-placement)
(at-xy board (x-of tile-placement) (y-of tile-placement)))
-(defun put-letter (board tile x y)
+(deftransaction put-letter (board tile x y)
(setf (aref (placed-tiles-of board) x y) tile))
(defclass tile (store-object)
@@ -81,7 +80,7 @@
(defmethod print-object ((tile tile) stream)
(print-unreadable-object (tile stream :type t :identity nil)
(with-slots (letter value) tile
- (format stream "~A (~A)" (when letter (char-name letter)) value))))
+ (format stream "~A (~A) ID:~A" (when letter (char-name letter)) value (store-object-id tile)))))
(defun make-tile (letter value)
(make-object 'tile :letter letter :value value))
@@ -146,6 +145,15 @@
t)
+(defmethod x-of ((placement list))
+ (first placement))
+
+(defmethod y-of ((placement list))
+ (second placement))
+
+(defmethod tile-of ((placement list))
+ (third placement))
+
(defun words-formed% (board placed-tiles verticalp)
"Scan for words that would be formed by placing PLACED-TILES on
BOARD. VERTICALP determines the scan order, if nil, the board is
Modified: branches/trunk-reorg/projects/scrabble/src/start-webserver.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/start-webserver.lisp 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/src/start-webserver.lisp 2007-11-14 05:27:46 UTC (rev 2276)
@@ -1,15 +1,11 @@
(in-package :scrabble.web)
-(defclass scrabble-store (mp-store random-mixin)
- ())
-
(defun open-scrabble-store (&optional delete-old-p)
(ignore-errors (close-store))
(when delete-old-p
(asdf:run-shell-command "rm -rf /tmp/scrabble-store/"))
- (make-instance 'scrabble-store :directory "/tmp/scrabble-store/"
- :subsystems (list (make-instance 'store-object-subsystem)
- (make-instance 'random-mixin-subsystem)))
+ (make-instance 'mp-store :directory "/tmp/scrabble-store/"
+ :subsystems (list (make-instance 'store-object-subsystem)))
(unless (class-instances 'user)
(format t "creating test users and game~%")
(let ((user1 (make-user "user1" :class 'player :full-name "User Eins"))
Modified: branches/trunk-reorg/projects/scrabble/src/web.lisp
===================================================================
--- branches/trunk-reorg/projects/scrabble/src/web.lisp 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/src/web.lisp 2007-11-14 05:27:46 UTC (rev 2276)
@@ -28,15 +28,22 @@
(encode-json-plist (list :remaining-tiles (remaining-tile-count tile-bag)) stream))
(defmethod encode-json ((move move) stream)
- (encode-json-plist (list :participant-login (user-login (player-of (participant-of move)))
+ (encode-json-plist (list :type "move"
+ :participant-login (user-login (player-of (participant-of move)))
:score (score-of move)
+ :placed-tiles (placed-tiles-of move)
:words (mapcar (lambda (word-cons)
(list :word (car word-cons)
:score (cdr word-cons)))
(words-formed-of move)))
stream))
-
+(defmethod encode-json ((move move-withdrawal) stream)
+ (encode-json-plist (list :type "move-withdrawal"
+ :participant-login (user-login (player-of (participant-of move)))
+ :reason (or (reason-of move) ""))
+ stream))
+
(defmethod encode-json ((board board) stream)
(princ #\[ stream)
(dotimes (x 15)
@@ -57,16 +64,15 @@
(length (tray-of participant)))))
stream))
-(define-easy-handler (login :uri "/login" :default-request-type :post)
+(define-easy-handler (login :uri "/login" :default-request-type :get)
(login password)
(format t "warning: password not checked~*~%" password)
(when (and login
(find-user login))
(start-session)
(setf (session-value :user) login)
- (redirect "/games"))
+ (redirect "/scrabble.html"))
(with-html-output-to-string (*standard-output* nil)
-
(:html
(:head
(:title "scrabble login"))
@@ -121,10 +127,11 @@
(progn
(let* ((game (find-game game))
(participant (find (find-user (session-value :user)) (participants-of game) :key #'player-of)))
- (scrabble:make-move game
- participant
- (parse-move participant move))
- (encode-json-plist (list :game game) s)))
+ (encode-json-plist
+ (list :move (scrabble:make-move game
+ participant
+ (parse-move participant move))
+ :tray (tray-of participant)) s)))
(error (e)
(encode-json-plist (list :error (princ-to-string e)) s)))))
Modified: branches/trunk-reorg/projects/scrabble/website/scrabble.html
===================================================================
--- branches/trunk-reorg/projects/scrabble/website/scrabble.html 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/website/scrabble.html 2007-11-14 05:27:46 UTC (rev 2276)
@@ -12,5 +12,7 @@
<body onload="init()">
<div id='playfield'>
</div>
+ <div style="position: absolute; right: 20px; top: 20px;"><a style="color: white;" href="/login?login=user1">user1</a></div>
+ <div style="position: absolute; right: 20px; top: 40px;"><a style="color: white;" href="/login?login=user2">user2</a></div>
</body>
</html>
\ No newline at end of file
Modified: branches/trunk-reorg/projects/scrabble/website/scrabble.js
===================================================================
--- branches/trunk-reorg/projects/scrabble/website/scrabble.js 2007-11-14 05:26:34 UTC (rev 2275)
+++ branches/trunk-reorg/projects/scrabble/website/scrabble.js 2007-11-14 05:27:46 UTC (rev 2276)
@@ -273,6 +273,7 @@
alert(response.error);
} else {
clearMove();
+ makeMyTray(map(function (entry) { return entry.letter }, response.tray))
}
}
1
0

[bknr-cvs] r2275 - in branches/trunk-reorg/thirdparty: . cl+ssl flexi-streams-0.13.1 flexi-streams-0.13.1/doc flexi-streams-0.13.1/test trivial-gray-streams trivial-https
by bknr@bknr.net 14 Nov '07
by bknr@bknr.net 14 Nov '07
14 Nov '07
Author: hhubner
Date: 2007-11-14 00:26:34 -0500 (Wed, 14 Nov 2007)
New Revision: 2275
Added:
branches/trunk-reorg/thirdparty/cl+ssl/
branches/trunk-reorg/thirdparty/cl+ssl/LICENSE
branches/trunk-reorg/thirdparty/cl+ssl/Makefile
branches/trunk-reorg/thirdparty/cl+ssl/bio.lisp
branches/trunk-reorg/thirdparty/cl+ssl/cl+ssl.asd
branches/trunk-reorg/thirdparty/cl+ssl/conditions.lisp
branches/trunk-reorg/thirdparty/cl+ssl/ffi-buffer-all.lisp
branches/trunk-reorg/thirdparty/cl+ssl/ffi-buffer-clisp.lisp
branches/trunk-reorg/thirdparty/cl+ssl/ffi-buffer.lisp
branches/trunk-reorg/thirdparty/cl+ssl/ffi.lisp
branches/trunk-reorg/thirdparty/cl+ssl/index.css
branches/trunk-reorg/thirdparty/cl+ssl/index.html
branches/trunk-reorg/thirdparty/cl+ssl/package.lisp
branches/trunk-reorg/thirdparty/cl+ssl/reload.lisp
branches/trunk-reorg/thirdparty/cl+ssl/streams.lisp
branches/trunk-reorg/thirdparty/cl+ssl/test.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/CHANGELOG
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/ascii.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/code-pages.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/doc/
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/doc/foo.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/doc/index.html
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/external-format.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/flexi-streams.asd
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/in-memory.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/input.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/iso-8859.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/koi8-r.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/lw-binary-stream.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/output.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/packages.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/specials.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/stream.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/strings.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/README
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_latin8_cr.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_latin8_crlf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_latin8_lf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_utf8_cr.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_utf8_crlf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_utf8_lf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_cp1252_cr.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_cp1252_crlf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_cp1252_lf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_latin1_cr.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_latin1_crlf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_latin1_lf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_utf8_cr.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_utf8_crlf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_utf8_lf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/packages.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_koi8r_cr.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_koi8r_crlf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_koi8r_lf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_utf8_cr.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_utf8_crlf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_utf8_lf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/test.lisp
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_ascii_cr.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_ascii_crlf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_ascii_lf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_utf8_cr.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_utf8_crlf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_utf8_lf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_cr_be.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_cr_le.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_crlf_be.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_crlf_le.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_lf_be.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_lf_le.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_cr_be.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_cr_le.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_crlf_be.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_crlf_le.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_lf_be.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_lf_le.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_utf8_cr.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_utf8_crlf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_utf8_lf.txt
branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/util.lisp
branches/trunk-reorg/thirdparty/trivial-gray-streams/
branches/trunk-reorg/thirdparty/trivial-gray-streams/COPYING
branches/trunk-reorg/thirdparty/trivial-gray-streams/Makefile
branches/trunk-reorg/thirdparty/trivial-gray-streams/README
branches/trunk-reorg/thirdparty/trivial-gray-streams/mixin.lisp
branches/trunk-reorg/thirdparty/trivial-gray-streams/package.lisp
branches/trunk-reorg/thirdparty/trivial-gray-streams/trivial-gray-streams.asd
branches/trunk-reorg/thirdparty/trivial-https/
branches/trunk-reorg/thirdparty/trivial-https/LICENSE
branches/trunk-reorg/thirdparty/trivial-https/README
branches/trunk-reorg/thirdparty/trivial-https/trivial-https.asd
branches/trunk-reorg/thirdparty/trivial-https/trivial-https.lisp
Log:
updating
Added: branches/trunk-reorg/thirdparty/cl+ssl/LICENSE
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/LICENSE 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/LICENSE 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,31 @@
+Copyright (C) 2001, 2003 Eric Marsden
+Copyright (C) ???? Jochen Schmidt
+Copyright (C) 2005 David Lichteblau
+Copyright (C) 2007 Pixel // pinterface
+
+* License first changed by Eric Marsden, Jochen Schmidt, and David Lichteblau
+ from plain LGPL to Lisp-LGPL in December 2005.
+
+* License then changed by Eric Marsden, Jochen Schmidt, and David Lichteblau
+ from Lisp-LGPL to MIT-style in January 2007.
+
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
Added: branches/trunk-reorg/thirdparty/cl+ssl/Makefile
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/Makefile 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/Makefile 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,3 @@
+.PHONY: clean
+clean:
+ rm -f *.fasl *.x86f *.fas *.ufsl *.lib *.pfsl
Added: branches/trunk-reorg/thirdparty/cl+ssl/bio.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/bio.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/bio.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,136 @@
+;;; Copyright (C) 2005 David Lichteblau
+;;;
+;;; See LICENSE for details.
+
+(in-package cl+ssl)
+
+(defconstant +bio-type-socket+ (logior 5 #x0400 #x0100))
+(defconstant +BIO_FLAGS_READ+ 1)
+(defconstant +BIO_FLAGS_WRITE+ 2)
+(defconstant +BIO_FLAGS_SHOULD_RETRY+ 8)
+(defconstant +BIO_CTRL_FLUSH+ 11)
+
+(cffi:defcstruct bio-method
+ (type :int)
+ (name :pointer)
+ (bwrite :pointer)
+ (bread :pointer)
+ (bputs :pointer)
+ (bgets :pointer)
+ (ctrl :pointer)
+ (create :pointer)
+ (destroy :pointer)
+ (callback-ctrl :pointer))
+
+(cffi:defcstruct bio
+ (method :pointer)
+ (callback :pointer)
+ (cb-arg :pointer)
+ (init :int)
+ (shutdown :int)
+ (flags :int)
+ (retry-reason :int)
+ (num :int)
+ (ptr :pointer)
+ (next-bio :pointer)
+ (prev-bio :pointer)
+ (references :int)
+ (num-read :unsigned-long)
+ (num-write :unsigned-long)
+ (crypto-ex-data-stack :pointer)
+ (crypto-ex-data-dummy :int))
+
+(defun make-bio-lisp-method ()
+ (let ((m (cffi:foreign-alloc 'bio-method)))
+ (setf (cffi:foreign-slot-value m 'bio-method 'type)
+ ;; fixme: this is wrong, but presumably still better than some
+ ;; random value here.
+ +bio-type-socket+)
+ (macrolet ((slot (name)
+ `(cffi:foreign-slot-value m 'bio-method ,name)))
+ (setf (slot 'name) (cffi:foreign-string-alloc "lisp"))
+ (setf (slot 'bwrite) (cffi:callback lisp-write))
+ (setf (slot 'bread) (cffi:callback lisp-read))
+ (setf (slot 'bputs) (cffi:callback lisp-puts))
+ (setf (slot 'bgets) (cffi:null-pointer))
+ (setf (slot 'ctrl) (cffi:callback lisp-ctrl))
+ (setf (slot 'create) (cffi:callback lisp-create))
+ (setf (slot 'destroy) (cffi:callback lisp-destroy))
+ (setf (slot 'callback-ctrl) (cffi:null-pointer)))
+ m))
+
+(defun bio-new-lisp ()
+ (bio-new *bio-lisp-method*))
+
+
+;;; "cargo cult"
+
+(cffi:defcallback lisp-write :int ((bio :pointer) (buf :pointer) (n :int))
+ bio
+ (dotimes (i n)
+ (write-byte (cffi:mem-ref buf :unsigned-char i) *socket*))
+ (finish-output *socket*)
+ n)
+
+(defun clear-retry-flags (bio)
+ (setf (cffi:foreign-slot-value bio 'bio 'flags)
+ (logandc2 (cffi:foreign-slot-value bio 'bio 'flags)
+ (logior +BIO_FLAGS_READ+
+ +BIO_FLAGS_WRITE+
+ +BIO_FLAGS_SHOULD_RETRY+))))
+
+(defun set-retry-read (bio)
+ (setf (cffi:foreign-slot-value bio 'bio 'flags)
+ (logior (cffi:foreign-slot-value bio 'bio 'flags)
+ +BIO_FLAGS_READ+
+ +BIO_FLAGS_SHOULD_RETRY+)))
+
+(cffi:defcallback lisp-read :int ((bio :pointer) (buf :pointer) (n :int))
+ bio buf n
+ (let ((i 0))
+ (handler-case
+ (unless (or (cffi:null-pointer-p buf) (null n))
+ (clear-retry-flags bio)
+ (when (or *blockp* (listen *socket*))
+ (setf (cffi:mem-ref buf :unsigned-char i) (read-byte *socket*))
+ (incf i))
+ (loop
+ while (and (< i n)
+ (or (null *partial-read-p*) (listen *socket*)))
+ do
+ (setf (cffi:mem-ref buf :unsigned-char i) (read-byte *socket*))
+ (incf i))
+ #+(or)
+ (when (zerop i) (set-retry-read bio)))
+ (end-of-file ()))
+ i))
+
+(cffi:defcallback lisp-puts :int ((bio :pointer) (buf :string))
+ bio buf
+ (error "lisp-puts not implemented"))
+
+(cffi:defcallback lisp-ctrl :int
+ ((bio :pointer) (cmd :int) (larg :long) (parg :pointer))
+ bio larg parg
+ (cond
+ ((eql cmd +BIO_CTRL_FLUSH+) 1)
+ (t
+ ;; (warn "lisp-ctrl(~A,~A,~A)" cmd larg parg)
+ 0)))
+
+(cffi:defcallback lisp-create :int ((bio :pointer))
+ (setf (cffi:foreign-slot-value bio 'bio 'init) 1)
+ (setf (cffi:foreign-slot-value bio 'bio 'num) 0)
+ (setf (cffi:foreign-slot-value bio 'bio 'ptr) (cffi:null-pointer))
+ (setf (cffi:foreign-slot-value bio 'bio 'flags) 0)
+ 1)
+
+(cffi:defcallback lisp-destroy :int ((bio :pointer))
+ (cond
+ ((cffi:null-pointer-p bio) 0)
+ (t
+ (setf (cffi:foreign-slot-value bio 'bio 'init) 0)
+ (setf (cffi:foreign-slot-value bio 'bio 'flags) 0)
+ 1)))
+
+(setf *bio-lisp-method* nil) ;force reinit if anything changed here
Added: branches/trunk-reorg/thirdparty/cl+ssl/cl+ssl.asd
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/cl+ssl.asd 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/cl+ssl.asd 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,27 @@
+;;; -*- mode: lisp -*-
+;;;
+;;; Copyright (C) 2001, 2003 Eric Marsden
+;;; Copyright (C) 2005 David Lichteblau
+;;; Copyright (C) 2007 Pixel // pinterface
+;;; "the conditions and ENSURE-SSL-FUNCALL are by Jochen Schmidt."
+;;;
+;;; See LICENSE for details.
+
+(defpackage :cl+ssl-system
+ (:use :cl :asdf))
+
+(in-package :cl+ssl-system)
+
+(defsystem :cl+ssl
+ :depends-on (:cffi :trivial-gray-streams :flexi-streams)
+ :serial t
+ :components
+ ((:file "package")
+ (:file "reload")
+ (:file "conditions")
+ (:file "ffi")
+ (:file "ffi-buffer-all")
+ #-clisp (:file "ffi-buffer")
+ #+clisp (:file "ffi-buffer-clisp")
+ (:file "streams")
+ (:file "bio")))
Added: branches/trunk-reorg/thirdparty/cl+ssl/conditions.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/conditions.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/conditions.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,211 @@
+;;; Copyright (C) 2001, 2003 Eric Marsden
+;;; Copyright (C) 2005 David Lichteblau
+;;; "the conditions and ENSURE-SSL-FUNCALL are by Jochen Schmidt."
+;;;
+;;; See LICENSE for details.
+
+(in-package :cl+ssl)
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (defconstant +ssl-error-none+ 0)
+ (defconstant +ssl-error-ssl+ 1)
+ (defconstant +ssl-error-want-read+ 2)
+ (defconstant +ssl-error-want-write+ 3)
+ (defconstant +ssl-error-want-x509-lookup+ 4)
+ (defconstant +ssl-error-syscall+ 5)
+ (defconstant +ssl-error-zero-return+ 6)
+ (defconstant +ssl-error-want-connect+ 7))
+
+
+;;; Condition hierarchy
+;;;
+(define-condition ssl-error (error)
+ ((queue :initform nil :initarg :queue :reader ssl-error-queue)))
+
+(define-condition ssl-error/handle (ssl-error)
+ ((ret :initarg :ret
+ :reader ssl-error-ret)
+ (handle :initarg :handle
+ :reader ssl-error-handle))
+ (:report (lambda (condition stream)
+ (format stream "Unspecified error ~A on handle ~A"
+ (ssl-error-ret condition)
+ (ssl-error-handle condition))
+ (write-sequence (ssl-error-queue condition) stream))))
+
+(define-condition ssl-error-initialize (ssl-error)
+ ((reason :initarg :reason
+ :reader ssl-error-reason))
+ (:report (lambda (condition stream)
+ (format stream "SSL initialization error: ~A"
+ (ssl-error-reason condition))
+ (write-sequence (ssl-error-queue condition) stream))))
+
+
+(define-condition ssl-error-want-something (ssl-error/handle)
+ ())
+
+;;;SSL_ERROR_NONE
+(define-condition ssl-error-none (ssl-error/handle)
+ ()
+ (:documentation
+ "The TLS/SSL I/O operation completed. This result code is returned if and
+ only if ret > 0.")
+ (:report (lambda (condition stream)
+ (format stream "The TLS/SSL operation on handle ~A completed. (return code: ~A)"
+ (ssl-error-handle condition)
+ (ssl-error-ret condition))
+ (write-sequence (ssl-error-queue condition) stream))))
+
+;; SSL_ERROR_ZERO_RETURN
+(define-condition ssl-error-zero-return (ssl-error/handle)
+ ()
+ (:documentation
+ "The TLS/SSL connection has been closed. If the protocol version is SSL 3.0
+ or TLS 1.0, this result code is returned only if a closure alert has
+ occurred in the protocol, i.e. if the connection has been closed cleanly.
+ Note that in this case SSL_ERROR_ZERO_RETURN
+ does not necessarily indicate that the underlying transport has been
+ closed.")
+ (:report (lambda (condition stream)
+ (format stream "The TLS/SSL connection on handle ~A has been closed. (return code: ~A)"
+ (ssl-error-handle condition)
+ (ssl-error-ret condition))
+ (write-sequence (ssl-error-queue condition) stream))))
+
+;; SSL_ERROR_WANT_READ
+(define-condition ssl-error-want-read (ssl-error-want-something)
+ ()
+ (:documentation
+ "The operation did not complete; the same TLS/SSL I/O function should be
+ called again later. If, by then, the underlying BIO has data available for
+ reading (if the result code is SSL_ERROR_WANT_READ) or allows writing data
+ (SSL_ERROR_WANT_WRITE), then some TLS/SSL protocol progress will take place,
+ i.e. at least part of an TLS/SSL record will be read or written. Note that
+ the retry may again lead to a SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE
+ condition. There is no fixed upper limit for the number of iterations that
+ may be necessary until progress becomes visible at application protocol
+ level.")
+ (:report (lambda (condition stream)
+ (format stream "The TLS/SSL operation on handle ~A did not complete: It wants a READ. (return code: ~A)"
+ (ssl-error-handle condition)
+ (ssl-error-ret condition))
+ (write-sequence (ssl-error-queue condition) stream))))
+
+;; SSL_ERROR_WANT_WRITE
+(define-condition ssl-error-want-write (ssl-error-want-something)
+ ()
+ (:documentation
+ "The operation did not complete; the same TLS/SSL I/O function should be
+ called again later. If, by then, the underlying BIO has data available for
+ reading (if the result code is SSL_ERROR_WANT_READ) or allows writing data
+ (SSL_ERROR_WANT_WRITE), then some TLS/SSL protocol progress will take place,
+ i.e. at least part of an TLS/SSL record will be read or written. Note that
+ the retry may again lead to a SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE
+ condition. There is no fixed upper limit for the number of iterations that
+ may be necessary until progress becomes visible at application protocol
+ level.")
+ (:report (lambda (condition stream)
+ (format stream "The TLS/SSL operation on handle ~A did not complete: It wants a WRITE. (return code: ~A)"
+ (ssl-error-handle condition)
+ (ssl-error-ret condition))
+ (write-sequence (ssl-error-queue condition) stream))))
+
+;; SSL_ERROR_WANT_CONNECT
+(define-condition ssl-error-want-connect (ssl-error-want-something)
+ ()
+ (:documentation
+ "The operation did not complete; the same TLS/SSL I/O function should be
+ called again later. The underlying BIO was not connected yet to the peer
+ and the call would block in connect()/accept(). The SSL
+ function should be called again when the connection is established. These
+ messages can only appear with a BIO_s_connect() or
+ BIO_s_accept() BIO, respectively. In order to find out, when
+ the connection has been successfully established, on many platforms
+ select() or poll() for writing on the socket file
+ descriptor can be used.")
+ (:report (lambda (condition stream)
+ (format stream "The TLS/SSL operation on handle ~A did not complete: It wants a connect first. (return code: ~A)"
+ (ssl-error-handle condition)
+ (ssl-error-ret condition))
+ (write-sequence (ssl-error-queue condition) stream))))
+
+;; SSL_ERROR_WANT_X509_LOOKUP
+(define-condition ssl-error-want-x509-lookup (ssl-error-want-something)
+ ()
+ (:documentation
+ "The operation did not complete because an application callback set by
+ SSL_CTX_set_client_cert_cb() has asked to be called again. The
+ TLS/SSL I/O function should be called again later. Details depend on the
+ application.")
+ (:report (lambda (condition stream)
+ (format stream "The TLS/SSL operation on handle ~A did not complete: An application callback wants to be called again. (return code: ~A)"
+ (ssl-error-handle condition)
+ (ssl-error-ret condition))
+ (write-sequence (ssl-error-queue condition) stream))))
+
+;; SSL_ERROR_SYSCALL
+(define-condition ssl-error-syscall (ssl-error/handle)
+ ((syscall :initarg :syscall))
+ (:documentation
+ "Some I/O error occurred. The OpenSSL error queue may contain more
+ information on the error. If the error queue is empty (i.e. ERR_get_error() returns 0),
+ ret can be used to find out more about the error: If ret == 0, an EOF was observed that
+ violates the protocol. If ret == -1, the underlying BIO reported an I/O error (for socket
+ I/O on Unix systems, consult errno for details).")
+ (:report (lambda (condition stream)
+ (if (zerop (err-get-error))
+ (case (ssl-error-ret condition)
+ (0 (format stream "An I/O error occurred: An unexpected EOF was observed on handle ~A. (return code: ~A)"
+ (ssl-error-handle condition)
+ (ssl-error-ret condition)))
+ (-1 (format stream "An I/O error occurred in the underlying BIO. (return code: ~A)"
+ (ssl-error-ret condition)))
+ (otherwise (format stream "An I/O error occurred: undocumented reason. (return code: ~A)"
+ (ssl-error-ret condition))))
+ (format stream "An UNKNOWN I/O error occurred in the underlying BIO. (return code: ~A)"
+ (ssl-error-ret condition)))
+ (write-sequence (ssl-error-queue condition) stream))))
+
+;; SSL_ERROR_SSL
+(define-condition ssl-error-ssl (ssl-error/handle)
+ ()
+ (:documentation
+ "A failure in the SSL library occurred, usually a protocol error. The
+ OpenSSL error queue contains more information on the error.")
+ (:report (lambda (condition stream)
+ (format stream
+ "A failure in the SSL library occurred on handle ~A. (Return code: ~A)"
+ (ssl-error-handle condition)
+ (ssl-error-ret condition))
+ (write-sequence (ssl-error-queue condition) stream))))
+
+(defun write-ssl-error-queue (stream)
+ (format stream "SSL error queue: ~%")
+ (loop
+ for error-code = (err-get-error)
+ until (zerop error-code)
+ do (format stream "~a~%" (err-error-string error-code (cffi:null-pointer)))))
+
+(defun ssl-signal-error (handle syscall error-code original-error)
+ (let ((queue (with-output-to-string (s) (write-ssl-error-queue s))))
+ (if (and (eql error-code #.+ssl-error-syscall+)
+ (not (zerop original-error)))
+ (error 'ssl-error-syscall
+ :handle handle
+ :ret error-code
+ :queue queue
+ :syscall syscall)
+ (error (case error-code
+ (#.+ssl-error-none+ 'ssl-error-none)
+ (#.+ssl-error-ssl+ 'ssl-error-ssl)
+ (#.+ssl-error-want-read+ 'ssl-error-want-read)
+ (#.+ssl-error-want-write+ 'ssl-error-want-write)
+ (#.+ssl-error-want-x509-lookup+ 'ssl-error-want-x509-lookup)
+ (#.+ssl-error-zero-return+ 'ssl-error-zero-return)
+ (#.+ssl-error-want-connect+ 'ssl-error-want-connect)
+ (#.+ssl-error-syscall+ 'ssl-error-zero-return)
+ (t 'ssl-error/handle))
+ :handle handle
+ :ret error-code
+ :queue queue))))
Added: branches/trunk-reorg/thirdparty/cl+ssl/ffi-buffer-all.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/ffi-buffer-all.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/ffi-buffer-all.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,12 @@
+(in-package :cl+ssl)
+
+(defconstant +initial-buffer-size+ 2048)
+
+(declaim
+ (inline
+ make-buffer
+ buffer-length
+ buffer-elt
+ set-buffer-elt
+ v/b-replace
+ b/v-replace))
Added: branches/trunk-reorg/thirdparty/cl+ssl/ffi-buffer-clisp.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/ffi-buffer-clisp.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/ffi-buffer-clisp.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,29 @@
+(in-package :cl+ssl)
+
+(defun make-buffer (size)
+ (cffi-sys:%foreign-alloc size))
+
+(defun buffer-length (buf)
+ (declare (ignore buf))
+ +initial-buffer-size+)
+
+(defun buffer-elt (buf index)
+ (ffi:memory-as buf 'ffi:uint8 index))
+(defun set-buffer-elt (buf index val)
+ (setf (ffi:memory-as buf 'ffi:uint8 index) val))
+(defsetf buffer-elt set-buffer-elt)
+
+(defun v/b-replace (vec buf &key (start1 0) end1 (start2 0) (end2 +initial-buffer-size+))
+ (replace
+ vec
+ (ffi:memory-as buf (ffi:parse-c-type `(ffi:c-array ffi:uint8 ,(- end2 start2))) start2)
+ :start1 start1
+ :end1 end1))
+(defun b/v-replace (buf vec &key (start1 0) (end1 +initial-buffer-size+) (start2 0) end2)
+ (setf
+ (ffi:memory-as buf (ffi:parse-c-type `(ffi:c-array ffi:uint8 ,(- end1 start1))) start1)
+ (subseq vec start2 end2)))
+
+(defmacro with-pointer-to-vector-data ((ptr buf) &body body)
+ `(let ((,ptr ,buf))
+ ,@body))
Added: branches/trunk-reorg/thirdparty/cl+ssl/ffi-buffer.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/ffi-buffer.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/ffi-buffer.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,22 @@
+(in-package :cl+ssl)
+
+(defun make-buffer (size)
+ (cffi-sys::make-shareable-byte-vector size))
+
+(defun buffer-length (buf)
+ (length buf))
+
+(defun buffer-elt (buf index)
+ (elt buf index))
+(defun set-buffer-elt (buf index val)
+ (setf (elt buf index) val))
+(defsetf buffer-elt set-buffer-elt)
+
+(defun v/b-replace (vec buf &key (start1 0) end1 (start2 0) end2)
+ (replace vec buf :start1 start1 :end1 end1 :start2 start2 :end2 end2))
+(defun b/v-replace (buf vec &key (start1 0) end1 (start2 0) end2)
+ (replace buf vec :start1 start1 :end1 end1 :start2 start2 :end2 end2))
+
+(defmacro with-pointer-to-vector-data ((ptr buf) &body body)
+ `(cffi-sys::with-pointer-to-vector-data (,ptr ,buf)
+ ,@body))
Added: branches/trunk-reorg/thirdparty/cl+ssl/ffi.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/ffi.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/ffi.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,248 @@
+;;; Copyright (C) 2001, 2003 Eric Marsden
+;;; Copyright (C) 2005 David Lichteblau
+;;; "the conditions and ENSURE-SSL-FUNCALL are by Jochen Schmidt."
+;;;
+;;; See LICENSE for details.
+
+(declaim
+ (optimize (speed 3) (space 1) (safety 1) (debug 0) (compilation-speed 0)))
+
+(in-package :cl+ssl)
+
+;;; Global state
+;;;
+(defvar *ssl-global-context* nil)
+(defvar *ssl-global-method* nil)
+(defvar *bio-lisp-method* nil)
+
+(defparameter *blockp* t)
+(defparameter *partial-read-p* nil)
+
+(defun ssl-initialized-p ()
+ (and *ssl-global-context* *ssl-global-method*))
+
+
+;;; Constants
+;;;
+(defconstant +random-entropy+ 256)
+
+(defconstant +ssl-filetype-pem+ 1)
+(defconstant +ssl-filetype-asn1+ 2)
+(defconstant +ssl-filetype-default+ 3)
+
+(defconstant +SSL_CTRL_SET_SESS_CACHE_MODE+ 44)
+
+
+;;; Misc
+;;;
+(defmacro while (cond &body body)
+ `(do () ((not ,cond)) ,@body))
+
+
+;;; Function definitions
+;;;
+(declaim (inline ssl-write ssl-read ssl-connect ssl-accept))
+
+(cffi:defctype ssl-method :pointer)
+(cffi:defctype ssl-ctx :pointer)
+(cffi:defctype ssl-pointer :pointer)
+
+(cffi:defcfun ("SSL_get_version" ssl-get-version)
+ :string
+ (ssl ssl-pointer))
+(cffi:defcfun ("SSL_load_error_strings" ssl-load-error-strings)
+ :void)
+(cffi:defcfun ("SSL_library_init" ssl-library-init)
+ :int)
+(cffi:defcfun ("SSLv2_client_method" ssl-v2-client-method)
+ ssl-method)
+(cffi:defcfun ("SSLv23_client_method" ssl-v23-client-method)
+ ssl-method)
+(cffi:defcfun ("SSLv23_server_method" ssl-v23-server-method)
+ ssl-method)
+(cffi:defcfun ("SSLv23_method" ssl-v23-method)
+ ssl-method)
+(cffi:defcfun ("SSLv3_client_method" ssl-v3-client-method)
+ ssl-method)
+(cffi:defcfun ("SSLv3_server_method" ssl-v3-server-method)
+ ssl-method)
+(cffi:defcfun ("SSLv3_method" ssl-v3-method)
+ ssl-method)
+(cffi:defcfun ("TLSv1_client_method" ssl-TLSv1-client-method)
+ ssl-method)
+(cffi:defcfun ("TLSv1_server_method" ssl-TLSv1-server-method)
+ ssl-method)
+(cffi:defcfun ("TLSv1_method" ssl-TLSv1-method)
+ ssl-method)
+
+(cffi:defcfun ("SSL_CTX_new" ssl-ctx-new)
+ ssl-ctx
+ (method ssl-method))
+(cffi:defcfun ("SSL_new" ssl-new)
+ ssl-pointer
+ (ctx ssl-ctx))
+(cffi:defcfun ("SSL_set_fd" ssl-set-fd)
+ :int
+ (ssl ssl-pointer)
+ (fd :int))
+(cffi:defcfun ("SSL_set_bio" ssl-set-bio)
+ :void
+ (ssl ssl-pointer)
+ (rbio :pointer)
+ (wbio :pointer))
+(cffi:defcfun ("SSL_get_error" ssl-get-error)
+ :int
+ (ssl ssl-pointer)
+ (ret :int))
+(cffi:defcfun ("SSL_set_connect_state" ssl-set-connect-state)
+ :void
+ (ssl ssl-pointer))
+(cffi:defcfun ("SSL_set_accept_state" ssl-set-accept-state)
+ :void
+ (ssl ssl-pointer))
+(cffi:defcfun ("SSL_connect" ssl-connect)
+ :int
+ (ssl ssl-pointer))
+(cffi:defcfun ("SSL_accept" ssl-accept)
+ :int
+ (ssl ssl-pointer))
+(cffi:defcfun ("SSL_write" ssl-write)
+ :int
+ (ssl ssl-pointer)
+ (buf :pointer)
+ (num :int))
+(cffi:defcfun ("SSL_read" ssl-read)
+ :int
+ (ssl ssl-pointer)
+ (buf :pointer)
+ (num :int))
+(cffi:defcfun ("SSL_shutdown" ssh-shutdown)
+ :void
+ (ssl ssl-pointer))
+(cffi:defcfun ("SSL_free" ssl-free)
+ :void
+ (ssl ssl-pointer))
+(cffi:defcfun ("SSL_CTX_free" ssl-ctx-free)
+ :void
+ (ctx ssl-ctx))
+(cffi:defcfun ("RAND_seed" rand-seed)
+ :void
+ (buf :pointer)
+ (num :int))
+(cffi:defcfun ("BIO_ctrl" bio-set-fd)
+ :long
+ (bio :pointer)
+ (cmd :int)
+ (larg :long)
+ (parg :pointer))
+(cffi:defcfun ("BIO_new_socket" bio-new-socket)
+ :pointer
+ (fd :int)
+ (close-flag :int))
+(cffi:defcfun ("BIO_new" bio-new)
+ :pointer
+ (method :pointer))
+
+(cffi:defcfun ("ERR_get_error" err-get-error)
+ :unsigned-long)
+(cffi:defcfun ("ERR_error_string" err-error-string)
+ :string
+ (e :unsigned-long)
+ (buf :pointer))
+
+(cffi:defcfun ("SSL_set_cipher_list" ssl-set-cipher-list)
+ :int
+ (ssl ssl-pointer)
+ (str :string))
+(cffi:defcfun ("SSL_use_RSAPrivateKey_file" ssl-use-rsa-privatekey-file)
+ :int
+ (ssl ssl-pointer)
+ (str :string)
+ ;; either +ssl-filetype-pem+ or +ssl-filetype-asn1+
+ (type :int))
+(cffi:defcfun
+ ("SSL_CTX_use_RSAPrivateKey_file" ssl-ctx-use-rsa-privatekey-file)
+ :int
+ (ctx ssl-ctx)
+ (type :int))
+(cffi:defcfun ("SSL_use_certificate_file" ssl-use-certificate-file)
+ :int
+ (ssl ssl-pointer)
+ (str :string)
+ (type :int))
+(cffi:defcfun ("SSL_CTX_load_verify_locations" ssl-ctx-load-verify-locations)
+ :int
+ (ctx ssl-ctx)
+ (CAfile :string)
+ (CApath :string))
+(cffi:defcfun ("SSL_CTX_set_client_CA_list" ssl-ctx-set-client-ca-list)
+ :void
+ (ctx ssl-ctx)
+ (list ssl-pointer))
+(cffi:defcfun ("SSL_load_client_CA_file" ssl-load-client-ca-file)
+ ssl-pointer
+ (file :string))
+
+(cffi:defcfun ("SSL_CTX_ctrl" ssl-ctx-ctrl)
+ :long
+ (ctx ssl-ctx)
+ (cmd :int)
+ (larg :long)
+ (parg :long))
+
+
+;;; Funcall wrapper
+;;;
+(defvar *socket*)
+
+(declaim (inline ensure-ssl-funcall))
+(defun ensure-ssl-funcall (*socket* handle func sleep-time &rest args)
+ (loop
+ (handler-case
+ (let ((rc (apply func args)))
+ (when (plusp rc)
+ (return rc))
+ (ssl-signal-error handle func (ssl-get-error handle rc) rc))
+ (ssl-error-want-something (condition)
+ (declare (ignore condition))
+ ;; FIXME: what is this SLEEP business for?
+ ;; Do we still need this?
+ (warn "sleeping in ensure-ssl-funcall")
+ (sleep sleep-time)))))
+
+
+;;; Initialization
+;;;
+(defun init-prng ()
+ ;; this initialization of random entropy is not necessary on
+ ;; Linux, since the OpenSSL library automatically reads from
+ ;; /dev/urandom if it exists. On Solaris it is necessary.
+ (let ((buf (cffi-sys::make-shareable-byte-vector +random-entropy+)))
+ (dotimes (i +random-entropy+)
+ (setf (elt buf i) (random 256)))
+ (cffi-sys::with-pointer-to-vector-data (ptr buf)
+ (rand-seed ptr +random-entropy+))))
+
+(defun ssl-ctx-set-session-cache-mode (ctx mode)
+ (ssl-ctx-ctrl ctx +SSL_CTRL_SET_SESS_CACHE_MODE+ mode 0))
+
+(defun initialize (&optional (method 'ssl-v23-method))
+ (setf *bio-lisp-method* (make-bio-lisp-method))
+ (ssl-load-error-strings)
+ (ssl-library-init)
+ (init-prng)
+ (setf *ssl-global-method* (funcall method))
+ (setf *ssl-global-context* (ssl-ctx-new *ssl-global-method*))
+ (ssl-ctx-set-session-cache-mode *ssl-global-context* 3))
+
+(defun ensure-initialized (&optional (method 'ssl-v23-method))
+ (unless (ssl-initialized-p)
+ (initialize method))
+ (unless *bio-lisp-method*
+ (setf *bio-lisp-method* (make-bio-lisp-method))))
+
+(defun reload ()
+ (cffi:load-foreign-library 'libssl)
+ (cffi:load-foreign-library 'libeay32)
+ (setf *ssl-global-context* nil)
+ (setf *ssl-global-method* nil))
Added: branches/trunk-reorg/thirdparty/cl+ssl/index.css
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/index.css 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/index.css 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,66 @@
+div.sidebar {
+ float: right;
+ background-color: #eeeeee;
+ border: 2pt solid black;
+ margin: 0em 2pt 1em 2em;
+ min-width: 15%;
+ padding: 0pt 5pt 5pt 5pt;
+}
+
+div.sidebar ul {
+ padding: 0pt 0pt 0pt 1em;
+ margin: 0 0 1em;
+}
+
+body {
+ color: #000000;
+ background-color: #ffffff;
+ margin-right: 0pt;
+ margin-bottom: 10%;
+ padding-left: 30px;
+}
+
+h1,h2 {
+ background-color: darkred;
+ color: white;
+ margin-left: -30px;
+}
+
+th {
+ background-color: darkred;
+ color: white;
+ text-align: left;
+}
+
+pre {
+ background-color: #eeeeee;
+ border: solid 1px #d0d0d0;
+ padding: 1em;
+ margin-right: 10%;
+}
+
+.def {
+ background-color: #ddddff;
+ font-weight: bold;
+}
+
+.nomargin {
+ margin-bottom: 0;
+ margin-top: 0;
+}
+
+.working {
+ background-color: #60c060;
+}
+
+.broken {
+ background-color: #ff6060;
+}
+
+.incomplete {
+ background-color: #ffff60;
+}
+
+.unknown {
+ background-color: #cccccc;
+}
Added: branches/trunk-reorg/thirdparty/cl+ssl/index.html
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/index.html 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/index.html 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+ <head>
+ <title>CL+SSL</title>
+ <link rel="stylesheet" type="text/css" href="index.css"/>
+ </head>
+ <body>
+ <h1>CL<em style="font-weight: normal">plus</em>SSL</h1>
+
+ <h3>Subprojects</h3>
+ <ul>
+ <li><a href="#cl+ssl">CL+SSL</a></li>
+ <li><a href="#trivial-https">trivial-https</a></li>
+ <li><a href="#trivial-gray-streams">trivial-gray-streams</a></li>
+ </ul>
+
+ <h3>News</h3>
+ <p>
+ 2007-xx-yy
+ </p>
+ <ul>
+ <li>
+ Fixed windows support, thanks to Matthew Kennedy and Vodonosov Anton.
+ </li>
+ </ul>
+ <p>
+ 2007-07-07
+ </p>
+ <ul>
+ <li>
+ Improved clisp support, thanks
+ to <a
+ href="http://web.kepibu.org/code/lisp/cl+ssl/">Pixel
+ // pinterface</a>, as well as client certificate support.
+ </li>
+ <li>
+ Re-introduced support for direct access to file descriptors as
+ an optimization. New function <tt>stream-fd</tt>. New keyword
+ argument <tt>close-callback</tt>.
+ </li>
+ </ul>
+ <p>
+ 2007-01-16: CL+SSL is now available under an MIT-style license.
+ </p>
+
+ <h3>Download</h3>
+ <p>
+ Anonymous CVS (<a href="http://common-lisp.net/cgi-bin/viewcvs.cgi/?cvsroot=cl-plus-ssl">browse</a>):
+ </p>
+ <pre>$ export CVSROOT=:pserver:anonymous@common-lisp.net:/project/cl-plus-ssl/cvsroot
+$ cvs login
+password: anonymous
+$ cvs co cl+ssl
+$ cvs co trivial-gray-streams
+$ cvs co trivial-https</pre>
+ <p>
+ <a
+ href="http://common-lisp.net/project/cl-plus-ssl/download/">Tarballs</a>
+ are also available (but not always up-to-date).
+ </p>
+ <p>
+ Note that you need the <tt>libssl-dev</tt> package on Debian to
+ load this package without manual configuration.
+ </p>
+
+ <p>
+ Send bug reports to <a
+ href="mailto:cl-plus-ssl-devel@common-lisp.net">cl-plus-ssl-devel(a)common-lisp.net</a>
+ (<a
+ href="http://common-lisp.net/cgi-bin/mailman/listinfo/cl-plus-ssl-devel">list
+ information</a>).
+ </p>
+
+ <a name="cl+ssl">
+ <h2>CL+SSL</h2>
+
+ <p>A simple Common Lisp interface to OpenSSL.</p>
+
+ <h3>About</h3>
+
+ <p>
+ This library is a fork of <a
+ href="http://www.cliki.net/SSL-CMUCL">SSL-CMUCL</a>. The original
+ SSL-CMUCL source code was written by Eric Marsden and includes
+ contributions by Jochen Schmidt. License: MIT-style.
+ </p>
+
+ <ul>
+ <li>
+ CL+SSL is portable code based on CFFI and gray streams.
+ </li>
+ <li>
+ It defines its own libssl BIO method, so that SSL I/O is
+ actually written over portable Lisp streams instead of bypassing
+ the streams and sending data over Unix file descriptors directly.
+ </li>
+ </ul>
+
+ <p>
+ Comparison chart:
+ </p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <thead>
+ <tr>
+ <th></th>
+ <th><b>FFI</b></th>
+ <th><b>Streams</b></th>
+ <th><b>Lisp-BIO</b></th>
+ </tr>
+ </thead>
+ <tr>
+ <td>CL+SSL</td>
+ <td>CFFI</td>
+ <td>gray<sup>1</sup>, buffering output</td>
+ <td>yes</td>
+ </tr>
+ <tr>
+ <td>CL-SSL</td>
+ <td>UFFI</td>
+ <td>gray, buffering I/O [<em>part of ACL-COMPAT</em>]</td>
+ <td>no</td>
+ </tr>
+ <tr>
+ <td>SSL-CMUCL</td>
+ <td>CMUCL/ALIEN</td>
+ <td>CMUCL, non-buffering</td>
+ <td>no</td>
+ </tr>
+ </table>
+ <p>
+ <sup>1</sup> Character I/O and external formats in CL+SSL
+ are provided
+ using <a href="http://weitz.de/flexi-streams/">flexi-streams</a>.
+ </p>
+
+ <h3>API functions</h3>
+ <p>
+ <div class="def">Function CL+SSL:STREAM-FD (stream)</div>
+ Return <tt>stream</tt>'s file descriptor as an integer, if
+ known. Otherwise return <tt>stream</tt> itself.
+ </p>
+ <p>
+ Pass the
+ return value of this function to <tt>make-ssl-client-stream</tt>
+ or <tt>make-ssl-servre-stream</tt>, which are faster when
+ accessing file descriptors directly.
+ </p>
+ <p>
+ <div class="def">Function CL+SSL:MAKE-SSL-CLIENT-STREAM (fd-or-stream &key external-format certificate key close-callback)</div>
+ Return an SSL stream for the client socket <tt>fd-or-stream</tt>.
+ All reads and writes to this SSL stream will be pushed through the
+ SSL connection.
+ </p>
+ <p>
+ If <tt>fd-or-stream</tt> is a lisp stream, it can
+ the SSL stream will close it automatically. File descriptors are
+ not closed automatically. However, if <tt>close-callback</tt> is
+ non-nil, it will be called with zero arguments when the SSL stream
+ is closed.
+
+ <tt>certificate</tt> is the path to a file containing the PEM-encoded
+ certificate for your client. <tt>key</tt> is the path to the PEM-encoded
+ key for the client, which must not be associated with a passphrase.
+ </p>
+ <p>
+ If <tt>external-format</tt> is <tt>nil</tt> (the default), a plain
+ <tt>(unsigned-byte 8)</tt> SSL stream is returned. With a
+ non-null <tt>external-format</tt>, a flexi-stream capable of
+ character I/O will be returned instead, with the specified value
+ as its initial external format.
+ </p>
+ <p>
+ <div class="def">Function CL+SSL:MAKE-SSL-SERVER-STREAM (fd-or-stream &key external-format certificate key close-callback)</div>
+ Return an SSL stream for the server socket <tt>fd-or-stream</tt>. All
+ reads and writes to this server stream will be pushed through the
+ OpenSSL library.
+ </p>
+ <p>
+ If <tt>fd-or-stream</tt> is a lisp stream, it can
+ the SSL stream will close it automatically. File descriptors are
+ not closed automatically. However, if <tt>close-callback</tt> is
+ non-nil, it will be called with zero arguments when the SSL stream
+ is closed.
+
+ <tt>certificate</tt> is the path to a file containing the PEM-encoded
+ certificate for your server. <tt>key</tt> is the path to the PEM-encoded
+ key for the server, which must not be associated with a
+ passphrase. See above for <tt>external-format</tt> handling.
+ </p>
+ <p>
+ <div class="def">Function CL+SSL:RELOAD ()</div>
+ Reload <tt>libssl</tt>. Call this function after restarting a Lisp
+ core with CL+SSL dumped into it on Lisp implementations that do
+ not reload shared libraries automatically.
+ </p>
+
+ <h3>Portability</h3>
+ <p>
+ CL+SSL requires CFFI with callback support.
+ </p>
+ <p>
+ Test results for Linux/x86, except OpenMCL which was tested on
+ Linux/PPC:
+ </p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <thead>
+ <tr>
+ <th><b>Lisp Implementation</b></th>
+ <th><b>Status</b></th>
+ <th><b>Comments</b></th>
+ </tr>
+ </thead>
+ <tr><td>OpenMCL</td><td class="working">Working</td></tr>
+ <tr><td>SBCL</td><td class="working">Working</td></tr>
+ <tr><td>CMU CL</td><td class="working">Working</td></tr>
+ <tr><td>CLISP</td><td class="working">Working</td></tr>
+ <tr><td>LispWorks</td><td class="working">Working</td></tr>
+ <tr>
+ <td>Allegro</td>
+ <td class="broken">Broken</td>
+ <td>segfault</td>
+ </tr>
+ <tr><td>Corman CL</td><td class="unknown">Unknown</td></tr>
+ <tr><td>Digitool MCL</td><td class="unknown">Unknown</td></tr>
+ <tr><td>Scieneer CL</td><td class="unknown">Unknown</td></tr>
+ <tr><td>ECL</td><td class="unknown">Unknown</td></tr>
+ <tr><td>GCL</td><td class="unknown">Unknown</td></tr>
+ </table>
+
+ <h3>TODO</h3>
+ <ul>
+ <li>CNAME checking!</li>
+ </ul>
+
+ <a name="trivial-https">
+ <h2>trivial-https</h2>
+
+ <p>
+ trivial-https is a fork of Brian
+ Mastenbrook's <a
+ href="http://www.cliki.net/trivial-http">trivial-http</a> adding
+ support for HTTPS using CL+SSL. License: MIT-style.
+ </p>
+
+ <p>
+ <b>
+ Note: The <a href="http://weitz.de/drakma/">Drakma</a> HTTP
+ client library by Weitz supports HTTPS using CL+SSL.
+ trivial-https will not be developed further; please use Drakma
+ instead.
+ </b>
+ </p>
+
+ <p>
+ <a href="http://common-lisp.net/cgi-bin/viewcvs.cgi/*checkout*/trivial-https/README?…">README</a>
+ </p>
+
+ <a name="trivial-gray-streams">
+ <h2>trivial-gray-streams</h2>
+
+ <p>
+ trivial-gray-streams provides an extremely thin compatibility
+ layer for gray streams. License: MIT-style.
+ </p>
+
+ <p>
+ <a href="http://common-lisp.net/cgi-bin/viewcvs.cgi/*checkout*/trivial-gray-streams/…">README</a>
+ </p>
+ </body>
+</html>
Added: branches/trunk-reorg/thirdparty/cl+ssl/package.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/package.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/package.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,15 @@
+;;; Copyright (C) 2001, 2003 Eric Marsden
+;;; Copyright (C) 2005 David Lichteblau
+;;; "the conditions and ENSURE-SSL-FUNCALL are by Jochen Schmidt."
+;;;
+;;; See LICENSE for details.
+
+(in-package :cl-user)
+
+(defpackage :cl+ssl
+ (:use :common-lisp :trivial-gray-streams)
+ (:export #:ensure-initialized
+ #:reload
+ #:stream-fd
+ #:make-ssl-client-stream
+ #:make-ssl-server-stream))
Added: branches/trunk-reorg/thirdparty/cl+ssl/reload.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/reload.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/reload.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,28 @@
+;;; Copyright (C) 2001, 2003 Eric Marsden
+;;; Copyright (C) 2005 David Lichteblau
+;;; "the conditions and ENSURE-SSL-FUNCALL are by Jochen Schmidt."
+;;;
+;;; See LICENSE for details.
+
+;;; We do this in an extra file so that it happens
+;;; - after the asd file has been loaded, so that users can
+;;; customize *libssl-pathname* between loading the asd and LOAD-OPing
+;;; the actual sources
+;;; - before ssl.lisp is loaded, which needs the library at compilation
+;;; time on some implemenations
+;;; - but not every time ffi.lisp is re-loaded as would happen if we
+;;; put this directly into ffi.lisp
+
+(in-package :cl+ssl)
+
+(cffi:define-foreign-library libssl
+ (:windows "libssl32.dll")
+ (:unix (:or "libssl.so.0.9.8" "libssl.so"))
+ (t (:default "libssl3")))
+
+(cffi:use-foreign-library libssl)
+
+(cffi:define-foreign-library libeay32
+ (:windows "libeay32.dll"))
+
+(cffi:use-foreign-library libeay32)
Added: branches/trunk-reorg/thirdparty/cl+ssl/streams.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/streams.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/streams.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,252 @@
+;;; Copyright (C) 2001, 2003 Eric Marsden
+;;; Copyright (C) 2005 David Lichteblau
+;;; Copyright (C) 2007 Pixel // pinterface
+;;; "the conditions and ENSURE-SSL-FUNCALL are by Jochen Schmidt."
+;;;
+;;; See LICENSE for details.
+
+(declaim
+ (optimize (speed 3) (space 1) (safety 1) (debug 0) (compilation-speed 0)))
+
+(in-package :cl+ssl)
+
+(defclass ssl-stream
+ (fundamental-binary-input-stream
+ fundamental-binary-output-stream
+ trivial-gray-stream-mixin)
+ ((ssl-stream-socket
+ :initarg :socket
+ :accessor ssl-stream-socket)
+ (close-callback
+ :initarg :close-callback
+ :accessor ssl-close-callback)
+ (handle
+ :initform nil
+ :accessor ssl-stream-handle)
+ (output-buffer
+ :initform (make-buffer +initial-buffer-size+)
+ :accessor ssl-stream-output-buffer)
+ (output-pointer
+ :initform 0
+ :accessor ssl-stream-output-pointer)
+ (input-buffer
+ :initform (make-buffer +initial-buffer-size+)
+ :accessor ssl-stream-input-buffer)
+ (peeked-byte
+ :initform nil
+ :accessor ssl-stream-peeked-byte)))
+
+(defmethod print-object ((object ssl-stream) stream)
+ (print-unreadable-object (object stream :type t)
+ (format stream "for ~A" (ssl-stream-socket object))))
+
+(defclass ssl-server-stream (ssl-stream)
+ ((certificate
+ :initarg :certificate
+ :accessor ssl-stream-certificate)
+ (key
+ :initarg :key
+ :accessor ssl-stream-key)))
+
+(defmethod stream-element-type ((stream ssl-stream))
+ '(unsigned-byte 8))
+
+(defmethod close ((stream ssl-stream) &key abort)
+ (declare (ignore abort))
+ (force-output stream)
+ (ssl-free (ssl-stream-handle stream))
+ (setf (ssl-stream-handle stream) nil)
+ (when (streamp (ssl-stream-socket stream))
+ (close (ssl-stream-socket stream)))
+ (when (functionp (ssl-close-callback stream))
+ (funcall (ssl-close-callback stream))))
+
+(defmethod open-stream-p ((stream ssl-stream))
+ (and (ssl-stream-handle stream) t))
+
+(defmethod stream-listen ((stream ssl-stream))
+ (or (ssl-stream-peeked-byte stream)
+ (setf (ssl-stream-peeked-byte stream)
+ (let* ((*blockp* nil)
+ (b (stream-read-byte stream)))
+ (if (eql b :eof) nil b)))))
+
+(defmethod stream-read-byte ((stream ssl-stream))
+ (or (ssl-stream-peeked-byte stream)
+ (let ((buf (ssl-stream-input-buffer stream)))
+ (handler-case
+ (with-pointer-to-vector-data (ptr buf)
+ (ensure-ssl-funcall (ssl-stream-socket stream)
+ (ssl-stream-handle stream)
+ #'ssl-read
+ 5.5
+ (ssl-stream-handle stream)
+ ptr
+ 1)
+ (buffer-elt buf 0))
+ (ssl-error-zero-return () ;SSL_read returns 0 on end-of-file
+ :eof)))))
+
+(defmethod stream-read-sequence ((stream ssl-stream) thing start end &key)
+ (check-type thing (simple-array (unsigned-byte 8) (*)))
+ (when (and (< start end) (ssl-stream-peeked-byte stream))
+ (setf (elt thing start) (ssl-stream-peeked-byte stream))
+ (setf (ssl-stream-peeked-byte stream) nil)
+ (incf start))
+ (let ((buf (ssl-stream-input-buffer stream)))
+ (loop
+ for length = (min (- end start) (buffer-length buf))
+ while (plusp length)
+ do
+ (handler-case
+ (with-pointer-to-vector-data (ptr buf)
+ (ensure-ssl-funcall (ssl-stream-socket stream)
+ (ssl-stream-handle stream)
+ #'ssl-read
+ 5.5
+ (ssl-stream-handle stream)
+ ptr
+ length)
+ (v/b-replace thing buf :start1 start :end1 (+ start length))
+ (incf start length))
+ (ssl-error-zero-return () ;SSL_read returns 0 on end-of-file
+ (return))))
+ start))
+
+(defmethod stream-write-byte ((stream ssl-stream) b)
+ (let ((buf (ssl-stream-output-buffer stream)))
+ (when (eql (buffer-length buf) (ssl-stream-output-pointer stream))
+ (force-output stream))
+ (setf (buffer-elt buf (ssl-stream-output-pointer stream)) b)
+ (incf (ssl-stream-output-pointer stream)))
+ b)
+
+(defmethod stream-write-sequence ((stream ssl-stream) thing start end &key)
+ (check-type thing (simple-array (unsigned-byte 8) (*)))
+ (let ((buf (ssl-stream-output-buffer stream)))
+ (when (> (+ (- end start) (ssl-stream-output-pointer stream)) (buffer-length buf))
+ ;; not enough space left? flush buffer.
+ (force-output stream)
+ ;; still doesn't fit?
+ (while (> (- end start) (buffer-length buf))
+ (b/v-replace buf thing :start2 start)
+ (incf start (buffer-length buf))
+ (setf (ssl-stream-output-pointer stream) (buffer-length buf))
+ (force-output stream)))
+ (b/v-replace buf thing
+ :start1 (ssl-stream-output-pointer stream)
+ :start2 start
+ :end2 end)
+ (incf (ssl-stream-output-pointer stream) (- end start)))
+ thing)
+
+(defmethod stream-finish-output ((stream ssl-stream))
+ (stream-force-output stream))
+
+(defmethod stream-force-output ((stream ssl-stream))
+ (let ((buf (ssl-stream-output-buffer stream))
+ (fill-ptr (ssl-stream-output-pointer stream))
+ (handle (ssl-stream-handle stream))
+ (socket (ssl-stream-socket stream)))
+ (when (plusp fill-ptr)
+ (with-pointer-to-vector-data (ptr buf)
+ (ensure-ssl-funcall socket handle #'ssl-write 0.5 handle ptr fill-ptr))
+ (setf (ssl-stream-output-pointer stream) 0))))
+
+
+;;; interface functions
+;;;
+(defun make-ssl-client-stream
+ (socket &key certificate key (method 'ssl-v23-method) external-format
+ close-callback)
+ "Returns an SSL stream for the client socket descriptor SOCKET.
+CERTIFICATE is the path to a file containing the PEM-encoded certificate for
+ your client. KEY is the path to the PEM-encoded key for the client, which
+must not be associated with a passphrase."
+ (ensure-initialized method)
+ (let ((stream (make-instance 'ssl-stream
+ :socket socket
+ :close-callback close-callback))
+ (handle (ssl-new *ssl-global-context*)))
+ (setf (ssl-stream-handle stream) handle)
+ (etypecase socket
+ (integer (ssl-set-fd handle socket))
+ (stream (ssl-set-bio handle (bio-new-lisp) (bio-new-lisp))))
+ (ssl-set-connect-state handle)
+ (when key
+ (unless (eql 1 (ssl-use-rsa-privatekey-file handle
+ key
+ +ssl-filetype-pem+))
+ (error 'ssl-error-initialize :reason "Can't load RSA private key ~A")))
+ (when certificate
+ (unless (eql 1 (ssl-use-certificate-file handle
+ certificate
+ +ssl-filetype-pem+))
+ (error 'ssl-error-initialize
+ :reason "Can't load certificate ~A" certificate)))
+ (ensure-ssl-funcall socket handle #'ssl-connect 0.25 handle)
+ (if external-format
+ (flexi-streams:make-flexi-stream stream
+ :external-format external-format)
+ stream)))
+
+(defun make-ssl-server-stream
+ (socket &key certificate key (method 'ssl-v23-method) external-format
+ close-callback)
+ "Returns an SSL stream for the server socket descriptor SOCKET.
+CERTIFICATE is the path to a file containing the PEM-encoded certificate for
+ your server. KEY is the path to the PEM-encoded key for the server, which
+must not be associated with a passphrase."
+ (ensure-initialized method)
+ (let ((stream (make-instance 'ssl-server-stream
+ :socket socket
+ :close-callback close-callback
+ :certificate certificate
+ :key key))
+ (handle (ssl-new *ssl-global-context*)))
+ (setf (ssl-stream-handle stream) handle)
+ (etypecase socket
+ (integer
+ (ssl-set-fd handle socket))
+ (stream
+ (let ((bio (bio-new-lisp)))
+ (ssl-set-bio handle bio bio))))
+ (ssl-set-accept-state handle)
+ (when (zerop (ssl-set-cipher-list handle "ALL"))
+ (error 'ssl-error-initialize :reason "Can't set SSL cipher list"))
+ (when key
+ (unless (eql 1 (ssl-use-rsa-privatekey-file handle
+ key
+ +ssl-filetype-pem+))
+ (error 'ssl-error-initialize :reason "Can't load RSA private key ~A")))
+ (when certificate
+ (unless (eql 1 (ssl-use-certificate-file handle
+ certificate
+ +ssl-filetype-pem+))
+ (error 'ssl-error-initialize
+ :reason "Can't load certificate ~A" certificate)))
+ (ensure-ssl-funcall socket handle #'ssl-accept 0.25 handle)
+ (if external-format
+ (flexi-streams:make-flexi-stream stream
+ :external-format external-format)
+ stream)))
+
+(defgeneric stream-fd (stream))
+(defmethod stream-fd (stream) stream)
+
+#+sbcl
+(defmethod stream-fd ((stream sb-sys:fd-stream))
+ (sb-sys:fd-stream-fd stream))
+
+#+cmu
+(defmethod stream-fd ((stream system:fd-stream))
+ (system:fd-stream-fd stream))
+
+#+openmcl
+(defmethod stream-fd ((stream ccl::basic-stream))
+ (ccl::ioblock-device (ccl::stream-ioblock stream t)))
+
+#+clisp
+(defmethod stream-fd ((stream stream))
+ ;; sockets appear to be direct instances of STREAM
+ (ignore-errors (socket:stream-handles stream)))
Added: branches/trunk-reorg/thirdparty/cl+ssl/test.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/cl+ssl/test.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/cl+ssl/test.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,103 @@
+;;; Copyright (C) 2001, 2003 Eric Marsden
+;;; Copyright (C) 2005 David Lichteblau
+;;; "the conditions and ENSURE-SSL-FUNCALL are by Jochen Schmidt."
+;;;
+;;; See LICENSE for details.
+
+#|
+(load "test.lisp")
+(ssl-test::test-https-client "www.google.com")
+(ssl-test::test-https-server)
+|#
+
+(defpackage :ssl-test
+ (:use :cl))
+(in-package :ssl-test)
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (asdf:operate 'asdf:load-op :trivial-sockets))
+
+(defun read-line-crlf (stream &optional eof-error-p)
+ (let ((s (make-string-output-stream)))
+ (loop
+ for empty = t then nil
+ for c = (read-char stream eof-error-p nil)
+ while (and c (not (eql c #\return)))
+ do
+ (unless (eql c #\newline)
+ (write-char c s))
+ finally
+ (return
+ (if empty nil (get-output-stream-string s))))))
+
+(defun test-nntps-client (&optional (host "snews.gmane.org") (port 563))
+ (let* ((fd (trivial-sockets:open-stream host port
+ :element-type '(unsigned-byte 8)))
+ (nntps (cl+ssl:make-ssl-client-stream fd :external-format :iso-8859-1)))
+ (format t "NNTPS> ~A~%" (read-line-crlf nntps))
+ (write-line "HELP" nntps)
+ (force-output nntps)
+ (loop :for line = (read-line-crlf nntps nil)
+ :until (string-equal "." line)
+ :do (format t "NNTPS> ~A~%" line))))
+
+
+;; open an HTTPS connection to a secure web server and make a
+;; HEAD request
+(defun test-https-client (host &optional (port 443))
+ (let* ((socket (trivial-sockets:open-stream
+ host
+ port
+ :element-type '(unsigned-byte 8)))
+ (https (cl+ssl:make-ssl-client-stream
+ (cl+ssl:stream-fd socket)
+ :external-format :iso-8859-1)))
+ (unwind-protect
+ (progn
+ (format https "HEAD / HTTP/1.0~%Host: ~a~%~%" host)
+ (force-output https)
+ (loop :for line = (read-line-crlf https nil)
+ :while line :do
+ (format t "HTTPS> ~a~%" line)))
+ (close socket)
+ (close https))))
+
+;; start a simple HTTPS server. See the mod_ssl documentation at
+;; <URL:http://www.modssl.org/> for information on generating the
+;; server certificate and key
+;;
+;; You can stress-test the server with
+;;
+;; siege -c 10 -u https://host:8080/foobar
+;;
+(defun test-https-server
+ (&key (port 8080)
+ (cert "/home/david/newcert.pem")
+ (key "/home/david/newkey.pem"))
+ (format t "~&SSL server listening on port ~d~%" port)
+ (trivial-sockets:with-server (server (:port port))
+ (loop
+ (let* ((socket (trivial-sockets:accept-connection
+ server
+ :element-type '(unsigned-byte 8)))
+ (client (cl+ssl:make-ssl-server-stream
+ (cl+ssl:stream-fd socket)
+ :external-format :iso-8859-1
+ :certificate cert
+ :key key)))
+ (unwind-protect
+ (progn
+ (loop :for line = (read-line-crlf client nil)
+ :while (> (length line) 1) :do
+ (format t "HTTPS> ~a~%" line))
+ (format client "HTTP/1.0 200 OK~%")
+ (format client "Server: SSL-CMUCL/1.1~%")
+ (format client "Content-Type: text/plain~%")
+ (terpri client)
+ (format client "G'day at ~A!~%"
+ (multiple-value-list (get-decoded-time)))
+ (format client "CL+SSL running in ~A ~A~%"
+ (lisp-implementation-type)
+ (lisp-implementation-version)))
+ (close socket)
+ (close client))))))
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/CHANGELOG
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/CHANGELOG 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/CHANGELOG 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,190 @@
+Version 0.13.1
+2007-10-11
+Small fix for AllegroCL's "modern" mode
+
+Version 0.13.0
+2007-09-13
+Better optimizations for STREAM-WRITE-SEQUENCE (thanks to Anton Vodonosov)
+Bugfix for STREAM-WRITE-BYTE
+
+Version 0.12.0
+2007-09-07
+Added "bound" for flexi input streams
+
+Version 0.11.2
+2007-04-06
+Fixed bug in STREAM-WRITE-STRING implementation (reported by quasi)
+
+Version 0.11.1
+2007-03-22
+More ugliness for a bit of output performance in special cases
+
+Version 0.11.0
+2007-03-09
+Re-factoring of how encoding errors are handled (patch by Anton Vodonosov)
+
+Version 0.10.3
+2007-02-19
+Fixed bug in UTF-16 output (patch by Stelian Ionescu)
+Fixed *SUBSTITUTION-CHAR* example in docs
+
+Version 0.10.2
+2007-01-12
+Another fix - sigh...
+
+Version 0.10.1
+2007-01-11
+Fixed the last change (thanks to Red Daly)
+
+Version 0.10.0
+2007-01-10
+Added transformers to in-memory streams (thanks to Chris Dean)
+Documentation fixes
+
+Version 0.9.1
+2006-12-27
+More performance improvements (thanks to Robert J. Macomber for SBCL hints)
+
+Version 0.9.0
+2006-12-27
+Complete re-factoring to improve performance and reduce consing (at least for LispWorks)
+Added some tests
+Added *PROVIDE-USE-VALUE-RESTART*
+Added FLEXI-STREAM-POSITION-SPEC-ERROR condition
+
+Version 0.8.0
+2006-11-14
+Added USE-VALUE restart for STREAM-READ-CHAR (thanks to Anton Vodonosov)
+Added *SUBSTITUTION-CHAR*
+
+Version 0.7.2
+2006-11-06
+Removed unnecessary CHECK-EOF-NO-HANG also for in-memory streams (see 0.5.8)
+
+Version 0.7.1
+2006-10-31
+Argh, missed the most important part...
+
+Version 0.7.0
+2006-10-31
+Added KOI8-R (thanks to Igor Plekhov)
+
+Version 0.6.6
+2006-10-06
+Made sure not to apply Gray stream generic function to underlying stream
+
+Version 0.6.5
+2006-10-06
+Optimized STREAM-WRITE-SEQUENCE and STREAM-READ-SEQUENCE for arrays of octets
+
+Version 0.6.4
+2006-10-05
+Made READ-BYTE/WRITE-BYTE the default behaviour, i.e. we only use the sequence functions for LW if necessary
+
+Version 0.6.3
+2006-10-02
+Fixed problems with CMUCL Gray streams implementation (reported by Ivan Toshkov)
+
+Version 0.6.2
+2006-09-23
+Added method for MAKE-LOAD-FORM which is needed for OpenMCL (reported by Robert Synnott, see Drakma mailing list)
+
+Version 0.6.1
+2006-09-15
+Switched FILE-POSITION implementation to TRIVIAL-GRAY-STREAMS (thanks to David Lichteblau)
+
+Version 0.6.0
+2006-09-13
+Implemented file positions for LispWorks
+
+Version 0.5.10
+2006-09-04
+Flexi streams can have binary element types now
+
+Version 0.5.9
+2006-09-01
+Added string functions
+
+Version 0.5.8
+2006-09-01
+CHECK-EOF-NO-HANG is not necessary
+Updated LW links in documentation
+Changed package handling in system definition (thanks to Christophe Rhodes)
+
+Version 0.5.7
+2006-06-29
+Removed incompatibility with AllegroCL, see mailing list archive for details
+
+Version 0.5.6
+2006-06-13
+Fixed Emacs mode lines (reported by Robert Goldman)
+
+Version 0.5.5
+2006-05-24
+Some small fixes for LW
+
+Version 0.5.4
+2006-05-18
+Workaround for CMUCL (thanks to Satyaki Das)
+
+Version 0.5.3
+2006-03-06
+Fixed more typos in stream.lisp
+Added missing exports in packages.lisp
+
+Version 0.5.2
+2006-01-26
+Fixed typos in stream.lisp (thanks to James Bielman)
+
+Version 0.5.1
+2005-12-14
+Some bugfixes in output.lisp (thanks to Jan Idzikowski)
+
+Version 0.5.0
+2005-12-11
+Added in-memory streams
+Exported types
+Added specific conditions
+
+Version 0.4.1
+2005-12-05
+Updated docs
+
+Version 0.4.0
+2005-12-05
+Added US-ASCII encoding
+Added *USE-REPLACEMENT-CHAR*
+
+Version 0.3.0
+2005-11-26
+Added UNREAD-BYTE and PEEK-BYTE
+
+Version 0.2.4
+2005-11-26
+WIN32:CODE-PAGE only for LispWorks
+
+Version 0.2.3
+2005-11-26
+Added STREAM-TERPRI to appease AllegroCL
+Fixed typo in docs
+
+Version 0.2.2
+2005-11-26
+Patch to make class precendence list work in AllegroCL (David Lichteblau)
+
+Version 0.2.1
+2005-11-25
+Adapted to new TRIVIAL-GRAY-STREAMS API (David Lichteblau)
+More changes for portability, specifically for SBCL (David Lichteblau)
+
+Version 0.2.0
+2005-11-25
+Portable version thanks to TRIVIAL-GRAY-STREAMS (David Lichteblau)
+
+Version 0.1.1
+2005-11-25
+Documentation enhancements
+
+Version 0.1.0
+2005-11-25
+Initial public release
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/ascii.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/ascii.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/ascii.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,35 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FLEXI-STREAMS; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/ascii.lisp,v 1.7 2007/01/01 23:46:49 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :flexi-streams)
+
+(defvar +ascii-table+
+ #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533)
+ "An array enumerating the character codes for the US-ASCII
+encoding.")
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/code-pages.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/code-pages.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/code-pages.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,62 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FLEXI-STREAMS; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/code-pages.lisp,v 1.5 2007/01/01 23:46:49 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :flexi-streams)
+
+;;; the following code was auto-generated with LWW
+
+(defvar +code-page-tables+
+ '((437 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 199 252 233 226 228 224 229 231 234 235 232 239 238 236 196 197 201 230 198 244 246 242 251 249 255 214 220 162 163 165 8359 402 225 237 243 250 241 209 170 186 191 8976 172 189 188 161 171 187 9617 9618 9619 9474 9508 9569 9570 9558 9557 9571 9553 9559 9565 9564 9563 9488 9492 9524 9516 9500 9472 9532 9566 9567 9562 9556 9577 9574 9568 9552 9580 9575 9576 9572 9573 9561 9560 9554 9555 9579 9578 9496 9484 9608 9604 9612 9616 9600 945 223 915 960 931 963 181 964 934 920 937 948 8734 966 949 8745 8801 177 8805 8804 8992 8993 247 8776 176 8729 183 8730 8319 178 9632 160))
+ (720 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 233 226 132 224 134 231 234 235 232 239 238 141 142 143 144 1617 1618 244 164 1600 251 249 1569 1570 1571 1572 163 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 171 187 9617 9618 9619 9474 9508 9569 9570 9558 9557 9571 9553 9559 9565 9564 9563 9488 9492 9524 9516 9500 9472 9532 9566 9567 9562 9556 9577 9574 9568 9552 9580 9575 9576 9572 9573 9561 9560 9554 9555 9579 9578 9496 9484 9608 9604 9612 9616 9600 1590 1591 1592 1593 1594 1601 181 1602 1603 1604 1605 1606 1607 1608 1609 1610 8801 1611 1612 1613 1614 1615 1616 8776 176 8729 183 8730 8319 178 9632 160))
+ (737 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 931 932 933 934 935 936 937 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 963 962 964 965 966 967 968 9617 9618 9619 9474 9508 9569 9570 9558 9557 9571 9553 9559 9565 9564 9563 9488 9492 9524 9516 9500 9472 9532 9566 9567 9562 9556 9577 9574 9568 9552 9580 9575 9576 9572 9573 9561 9560 9554 9555 9579 9578 9496 9484 9608 9604 9612 9616 9600 969 940 941 942 970 943 972 973 971 974 902 904 905 906 908 910 911 177 8805 8804 938 939 247 8776 176 8729 183 8730 8319 178 9632 160))
+ (775 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 262 252 233 257 228 291 229 263 322 275 342 343 299 377 196 197 201 230 198 333 246 290 162 346 347 214 220 248 163 216 215 164 256 298 243 379 380 378 8221 166 169 174 172 189 188 321 171 187 9617 9618 9619 9474 9508 260 268 280 278 9571 9553 9559 9565 302 352 9488 9492 9524 9516 9500 9472 9532 370 362 9562 9556 9577 9574 9568 9552 9580 381 261 269 281 279 303 353 371 363 382 9496 9484 9608 9604 9612 9616 9600 211 223 332 323 245 213 181 324 310 311 315 316 326 274 325 8217 173 177 8220 190 182 167 247 8222 176 8729 183 185 179 178 9632 160))
+ (850 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 199 252 233 226 228 224 229 231 234 235 232 239 238 236 196 197 201 230 198 244 246 242 251 249 255 214 220 248 163 216 215 402 225 237 243 250 241 209 170 186 191 174 172 189 188 161 171 187 9617 9618 9619 9474 9508 193 194 192 169 9571 9553 9559 9565 162 165 9488 9492 9524 9516 9500 9472 9532 227 195 9562 9556 9577 9574 9568 9552 9580 164 240 208 202 203 200 305 205 206 207 9496 9484 9608 9604 166 204 9600 211 223 212 210 245 213 181 254 222 218 219 217 253 221 175 180 173 177 8215 190 182 167 247 184 176 168 183 185 179 178 9632 160))
+ (852 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 199 252 233 226 228 367 263 231 322 235 336 337 238 377 196 262 201 313 314 244 246 317 318 346 347 214 220 356 357 321 215 269 225 237 243 250 260 261 381 382 280 281 172 378 268 351 171 187 9617 9618 9619 9474 9508 193 194 282 350 9571 9553 9559 9565 379 380 9488 9492 9524 9516 9500 9472 9532 258 259 9562 9556 9577 9574 9568 9552 9580 164 273 272 270 203 271 327 205 206 283 9496 9484 9608 9604 354 366 9600 211 223 212 323 324 328 352 353 340 218 341 368 253 221 355 180 173 733 731 711 728 167 247 184 176 168 729 369 344 345 9632 160))
+ (855 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 1106 1026 1107 1027 1105 1025 1108 1028 1109 1029 1110 1030 1111 1031 1112 1032 1113 1033 1114 1034 1115 1035 1116 1036 1118 1038 1119 1039 1102 1070 1098 1066 1072 1040 1073 1041 1094 1062 1076 1044 1077 1045 1092 1060 1075 1043 171 187 9617 9618 9619 9474 9508 1093 1061 1080 1048 9571 9553 9559 9565 1081 1049 9488 9492 9524 9516 9500 9472 9532 1082 1050 9562 9556 9577 9574 9568 9552 9580 164 1083 1051 1084 1052 1085 1053 1086 1054 1087 9496 9484 9608 9604 1055 1103 9600 1071 1088 1056 1089 1057 1090 1058 1091 1059 1078 1046 1074 1042 1100 1068 8470 173 1099 1067 1079 1047 1096 1064 1101 1069 1097 1065 1095 1063 167 9632 160))
+ (857 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 199 252 233 226 228 224 229 231 234 235 232 239 238 305 196 197 201 230 198 244 246 242 251 249 304 214 220 248 163 216 350 351 225 237 243 250 241 209 286 287 191 174 172 189 188 161 171 187 9617 9618 9619 9474 9508 193 194 192 169 9571 9553 9559 9565 162 165 9488 9492 9524 9516 9500 9472 9532 227 195 9562 9556 9577 9574 9568 9552 9580 164 186 170 202 203 200 65533 205 206 207 9496 9484 9608 9604 166 204 9600 211 223 212 210 245 213 181 65533 215 218 219 217 236 255 175 180 173 177 65533 190 182 167 247 184 176 168 183 185 179 178 9632 160))
+ (860 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 199 252 233 226 227 224 193 231 234 202 232 205 212 236 195 194 201 192 200 244 245 242 218 249 204 213 220 162 163 217 8359 211 225 237 243 250 241 209 170 186 191 210 172 189 188 161 171 187 9617 9618 9619 9474 9508 9569 9570 9558 9557 9571 9553 9559 9565 9564 9563 9488 9492 9524 9516 9500 9472 9532 9566 9567 9562 9556 9577 9574 9568 9552 9580 9575 9576 9572 9573 9561 9560 9554 9555 9579 9578 9496 9484 9608 9604 9612 9616 9600 945 223 915 960 931 963 181 964 934 920 937 948 8734 966 949 8745 8801 177 8805 8804 8992 8993 247 8776 176 8729 183 8730 8319 178 9632 160))
+ (861 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 199 252 233 226 228 224 229 231 234 235 232 208 240 222 196 197 201 230 198 244 246 254 251 221 253 214 220 248 163 216 8359 402 225 237 243 250 193 205 211 218 191 8976 172 189 188 161 171 187 9617 9618 9619 9474 9508 9569 9570 9558 9557 9571 9553 9559 9565 9564 9563 9488 9492 9524 9516 9500 9472 9532 9566 9567 9562 9556 9577 9574 9568 9552 9580 9575 9576 9572 9573 9561 9560 9554 9555 9579 9578 9496 9484 9608 9604 9612 9616 9600 945 223 915 960 931 963 181 964 934 920 937 948 8734 966 949 8745 8801 177 8805 8804 8992 8993 247 8776 176 8729 183 8730 8319 178 9632 160))
+ (862 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 162 163 165 8359 402 225 237 243 250 241 209 170 186 191 8976 172 189 188 161 171 187 9617 9618 9619 9474 9508 9569 9570 9558 9557 9571 9553 9559 9565 9564 9563 9488 9492 9524 9516 9500 9472 9532 9566 9567 9562 9556 9577 9574 9568 9552 9580 9575 9576 9572 9573 9561 9560 9554 9555 9579 9578 9496 9484 9608 9604 9612 9616 9600 945 223 915 960 931 963 181 964 934 920 937 948 8734 966 949 8745 8801 177 8805 8804 8992 8993 247 8776 176 8729 183 8730 8319 178 9632 160))
+ (863 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 199 252 233 226 194 224 182 231 234 235 232 239 238 8215 192 167 201 200 202 244 203 207 251 249 164 212 220 162 163 217 219 402 166 180 243 250 168 184 179 175 206 8976 172 189 188 190 171 187 9617 9618 9619 9474 9508 9569 9570 9558 9557 9571 9553 9559 9565 9564 9563 9488 9492 9524 9516 9500 9472 9532 9566 9567 9562 9556 9577 9574 9568 9552 9580 9575 9576 9572 9573 9561 9560 9554 9555 9579 9578 9496 9484 9608 9604 9612 9616 9600 945 223 915 960 931 963 181 964 934 920 937 948 8734 966 949 8745 8801 177 8805 8804 8992 8993 247 8776 176 8729 183 8730 8319 178 9632 160))
+ (864 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 176 183 8729 8730 9618 9472 9474 9532 9508 9516 9500 9524 9488 9484 9492 9496 946 8734 966 177 189 188 8776 171 187 65271 65272 155 156 65275 65276 159 160 173 65154 163 164 65156 65533 65533 65166 65167 65173 65177 1548 65181 65185 65189 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 65233 1563 65201 65205 65209 1567 162 65152 65153 65155 65157 65226 65163 65165 65169 65171 65175 65179 65183 65187 65191 65193 65195 65197 65199 65203 65207 65211 65215 65217 65221 65227 65231 166 172 247 215 65225 1600 65235 65239 65243 65247 65251 65255 65259 65261 65263 65267 65213 65228 65230 65229 65249 65149 1617 65253 65257 65260 65264 65266 65232 65237 65269 65270 65245 65241 65265 9632 65533))
+ (865 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 199 252 233 226 228 224 229 231 234 235 232 239 238 236 196 197 201 230 198 244 246 242 251 249 255 214 220 248 163 216 8359 402 225 237 243 250 241 209 170 186 191 8976 172 189 188 161 171 164 9617 9618 9619 9474 9508 9569 9570 9558 9557 9571 9553 9559 9565 9564 9563 9488 9492 9524 9516 9500 9472 9532 9566 9567 9562 9556 9577 9574 9568 9552 9580 9575 9576 9572 9573 9561 9560 9554 9555 9579 9578 9496 9484 9608 9604 9612 9616 9600 945 223 915 960 931 963 181 964 934 920 937 948 8734 966 949 8745 8801 177 8805 8804 8992 8993 247 8776 176 8729 183 8730 8319 178 9632 160))
+ (866 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 9617 9618 9619 9474 9508 9569 9570 9558 9557 9571 9553 9559 9565 9564 9563 9488 9492 9524 9516 9500 9472 9532 9566 9567 9562 9556 9577 9574 9568 9552 9580 9575 9576 9572 9573 9561 9560 9554 9555 9579 9578 9496 9484 9608 9604 9612 9616 9600 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1025 1105 1028 1108 1031 1111 1038 1118 176 8729 183 8730 8470 164 9632 160))
+ (869 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 902 135 183 172 166 8216 8217 904 8213 905 906 938 908 147 148 910 939 169 911 178 179 940 163 941 942 943 970 912 972 973 913 914 915 916 917 918 919 189 920 921 171 187 9617 9618 9619 9474 9508 922 923 924 925 9571 9553 9559 9565 926 927 9488 9492 9524 9516 9500 9472 9532 928 929 9562 9556 9577 9574 9568 9552 9580 931 932 933 934 935 936 937 945 946 947 9496 9484 9608 9604 948 949 9600 950 951 952 953 954 955 956 957 958 959 960 961 963 962 964 900 173 177 965 966 967 167 968 901 176 168 969 971 944 974 9632 160))
+ (1250 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 8364 129 8218 131 8222 8230 8224 8225 136 8240 352 8249 346 356 381 377 144 8216 8217 8220 8221 8226 8211 8212 152 8482 353 8250 347 357 382 378 160 711 728 321 164 260 166 167 168 169 350 171 172 173 174 379 176 177 731 322 180 181 182 183 184 261 351 187 317 733 318 380 340 193 194 258 196 313 262 199 268 201 280 203 282 205 206 270 272 323 327 211 212 336 214 215 344 366 218 368 220 221 354 223 341 225 226 259 228 314 263 231 269 233 281 235 283 237 238 271 273 324 328 243 244 337 246 247 345 367 250 369 252 253 355 729))
+ (1251 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 1026 1027 8218 1107 8222 8230 8224 8225 8364 8240 1033 8249 1034 1036 1035 1039 1106 8216 8217 8220 8221 8226 8211 8212 152 8482 1113 8250 1114 1116 1115 1119 160 1038 1118 1032 164 1168 166 167 1025 169 1028 171 172 173 174 1031 176 177 1030 1110 1169 181 182 183 1105 8470 1108 187 1112 1029 1109 1111 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103))
+ (1252 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 8364 129 8218 402 8222 8230 8224 8225 710 8240 352 8249 338 141 381 143 144 8216 8217 8220 8221 8226 8211 8212 732 8482 353 8250 339 157 382 376 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255))
+ (1253 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 8364 129 8218 402 8222 8230 8224 8225 136 8240 138 8249 140 141 142 143 144 8216 8217 8220 8221 8226 8211 8212 152 8482 154 8250 156 157 158 159 160 901 902 163 164 165 166 167 168 169 65533 171 172 173 174 8213 176 177 178 179 900 181 182 183 904 905 906 187 908 189 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 65533 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 65533))
+ (1254 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 8364 129 8218 402 8222 8230 8224 8225 710 8240 352 8249 338 141 142 143 144 8216 8217 8220 8221 8226 8211 8212 732 8482 353 8250 339 157 158 376 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 286 209 210 211 212 213 214 215 216 217 218 219 220 304 350 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 287 241 242 243 244 245 246 247 248 249 250 251 252 305 351 255))
+ (1255 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 8364 129 8218 402 8222 8230 8224 8225 710 8240 138 8249 140 141 142 143 144 8216 8217 8220 8221 8226 8211 8212 732 8482 154 8250 156 157 158 159 160 161 162 163 8362 165 166 167 168 169 215 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 247 187 188 189 190 191 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1520 1521 1522 1523 1524 65533 65533 65533 65533 65533 65533 65533 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 65533 65533 8206 8207 65533))
+ (1256 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 8364 1662 8218 402 8222 8230 8224 8225 710 8240 1657 8249 338 1670 1688 1672 1711 8216 8217 8220 8221 8226 8211 8212 1705 8482 1681 8250 339 8204 8205 1722 160 1548 162 163 164 165 166 167 168 169 1726 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 1563 187 188 189 190 1567 1729 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 215 1591 1592 1593 1594 1600 1601 1602 1603 224 1604 226 1605 1606 1607 1608 231 232 233 234 235 1609 1610 238 239 1611 1612 1613 1614 244 1615 1616 247 1617 249 1618 251 252 8206 8207 1746))
+ (1257 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 8364 129 8218 131 8222 8230 8224 8225 136 8240 138 8249 140 168 711 184 144 8216 8217 8220 8221 8226 8211 8212 152 8482 154 8250 156 175 731 159 160 65533 162 163 164 65533 166 167 216 169 342 171 172 173 174 198 176 177 178 179 180 181 182 183 248 185 343 187 188 189 190 230 260 302 256 262 196 197 280 274 268 201 377 278 290 310 298 315 352 323 325 211 332 213 214 215 370 321 346 362 220 379 381 223 261 303 257 263 228 229 281 275 269 233 378 279 291 311 299 316 353 324 326 243 333 245 246 247 371 322 347 363 252 380 382 729))
+ (1258 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 8364 129 8218 402 8222 8230 8224 8225 710 8240 138 8249 338 141 142 143 144 8216 8217 8220 8221 8226 8211 8212 732 8482 154 8250 339 157 158 376 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 258 196 197 198 199 200 201 202 203 768 205 206 207 272 209 777 211 212 416 214 215 216 217 218 219 220 431 771 223 224 225 226 259 228 229 230 231 232 233 234 235 769 237 238 239 273 241 803 243 244 417 246 247 248 249 250 251 252 432 8363 255)))
+ "A list of 8-bit Windows code pages where each element is a
+cons with the car being the ID of the code page and the cdr being
+a vector enumerating the corresponding character codes.")
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/doc/foo.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/doc/foo.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/doc/index.html
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/doc/index.html 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/doc/index.html 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,1044 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>FLEXI-STREAMS - Flexible bivalent streams for Common Lisp</title>
+ <style type="text/css">
+ pre { padding:5px; background-color:#e0e0e0 }
+ h3, h4 { text-decoration: underline; }
+ a { text-decoration: none; padding: 1px 2px 1px 2px; }
+ a:visited { text-decoration: none; padding: 1px 2px 1px 2px; }
+ a:hover { text-decoration: none; padding: 1px 1px 1px 1px; border: 1px solid #000000; }
+ a:focus { text-decoration: none; padding: 1px 2px 1px 2px; border: none; }
+ a.none { text-decoration: none; padding: 0; }
+ a.none:visited { text-decoration: none; padding: 0; }
+ a.none:hover { text-decoration: none; border: none; padding: 0; }
+ a.none:focus { text-decoration: none; border: none; padding: 0; }
+ a.noborder { text-decoration: none; padding: 0; }
+ a.noborder:visited { text-decoration: none; padding: 0; }
+ a.noborder:hover { text-decoration: none; border: none; padding: 0; }
+ a.noborder:focus { text-decoration: none; border: none; padding: 0; }
+ </style>
+</head>
+
+<body bgcolor=white>
+
+<h2>FLEXI-STREAMS - Flexible bivalent streams for Common Lisp</h2>
+
+<blockquote>
+<br> <br><h3><a name=abstract class=none>Abstract</a></h3>
+
+FLEXI-STREAMS implements "virtual" bivalent streams that can be
+layered atop real binary or bivalent streams and that can be used to
+read and write character data in various single- or multi-octet
+encodings which can be changed on the fly. It also supplies
+<em>in-memory</em> binary streams which are similar to string streams.
+<p>
+The library needs a Common Lisp implementation that
+supports <a
+href="http://www.nhplace.com/kent/CL/Issues/stream-definition-by-user.html"><em>Gray
+streams</em></a> and relies on David
+Lichteblau's <a
+href="http://www.cliki.net/trivial-gray-streams">trivial-gray-streams</a>
+to offer portability between different Lisps.
+<p>
+The code comes with
+a <a
+href="http://www.opensource.org/licenses/bsd-license.php">BSD-style
+license</a> so you can basically do with it whatever you want.
+
+<p>
+<font color=red>Download shortcut:</font> <a href="http://weitz.de/files/flexi-streams.tar.gz">http://weitz.de/files/flexi-streams.tar.gz</a>.
+</blockquote>
+
+<br> <br><h3><a class=none name="contents">Contents</a></h3>
+<ol>
+ <li><a href="#example">Example usage</a>
+ <li><a href="#install">Download and installation</a>
+ <li><a href="#backward-compatibility">Backward compatibility with version 0.10.3 and before</a>
+ <li><a href="#mail">Support and mailing lists</a>
+ <li><a href="#dictionary">The FLEXI-STREAMS dictionary</a>
+ <ol>
+ <li><a href="#external-formats">External formats</a>
+ <ol>
+ <li><a href="#make-external-format"><code>make-external-format</code></a>
+ <li><a href="#external-format-name"><code>external-format-name</code></a>
+ <li><a href="#external-format-eol-style"><code>external-format-eol-style</code></a>
+ <li><a href="#external-format-little-endian"><code>external-format-little-endian</code></a>
+ <li><a href="#external-format-id"><code>external-format-id</code></a>
+ <li><a href="#external-format-equal"><code>external-format-equal</code></a>
+ <li><a href="#*default-eol-style*"><code>*default-eol-style*</code></a>
+ <li><a href="#*default-little-endian*"><code>*default-little-endian*</code></a>
+ </ol>
+ <li><a href="#flexi-streams">Flexi streams</a>
+ <ol>
+ <li><a href="#flexi-stream"><code>flexi-stream</code></a>
+ <li><a href="#flexi-input-stream"><code>flexi-input-stream</code></a>
+ <li><a href="#flexi-output-stream"><code>flexi-output-stream</code></a>
+ <li><a href="#flexi-io-stream"><code>flexi-io-stream</code></a>
+ <li><a href="#make-flexi-stream"><code>make-flexi-stream</code></a>
+ <li><a href="#flexi-stream-external-format"><code>flexi-stream-external-format</code></a>
+ <li><a href="#flexi-stream-element-type"><code>flexi-stream-element-type</code></a>
+ <li><a href="#flexi-stream-column"><code>flexi-stream-column</code></a>
+ <li><a href="#flexi-stream-position"><code>flexi-stream-position</code></a>
+ <li><a href="#flexi-stream-bound"><code>flexi-stream-bound</code></a>
+ <li><a href="#flexi-stream-stream"><code>flexi-stream-stream</code></a>
+ <li><a href="#unread-byte"><code>unread-byte</code></a>
+ <li><a href="#peek-byte"><code>peek-byte</code></a>
+ <li><a href="#*substitution-char*"><code>*substitution-char*</code></a>
+ <li><a href="#octet"><code>octet</code></a>
+ <li><a href="#flexi-stream-error"><code>flexi-stream-error</code></a>
+ <li><a href="#flexi-stream-encoding-error"><code>flexi-stream-encoding-error</code></a>
+ <li><a href="#flexi-stream-element-type-error"><code>flexi-stream-element-type-error</code></a>
+ <li><a href="#flexi-stream-element-type-error-element-type"><code>flexi-stream-element-type-error-element-type</code></a>
+ <li><a href="#flexi-stream-position-spec-error"><code>flexi-stream-position-spec-error</code></a>
+ <li><a href="#flexi-stream-position-spec-error-position-spec"><code>flexi-stream-position-spec-error-position-spec</code></a>
+ </ol>
+ <li><a href="#in-memory">In-memory streams</a>
+ <ol>
+ <li><a href="#in-memory-stream"><code>in-memory-stream</code></a>
+ <li><a href="#in-memory-input-stream"><code>in-memory-input-stream</code></a>
+ <li><a href="#in-memory-output-stream"><code>in-memory-output-stream</code></a>
+ <li><a href="#list-stream"><code>list-stream</code></a>
+ <li><a href="#vector-stream"><code>vector-stream</code></a>
+ <li><a href="#make-in-memory-input-stream"><code>make-in-memory-input-stream</code></a>
+ <li><a href="#make-in-memory-output-stream"><code>make-in-memory-output-stream</code></a>
+ <li><a href="#get-output-stream-sequence"><code>get-output-stream-sequence</code></a>
+ <li><a href="#output-stream-sequence-length"><code>output-stream-sequence-length</code></a>
+ <li><a href="#with-input-from-sequence"><code>with-input-from-sequence</code></a>
+ <li><a href="#with-output-to-sequence"><code>with-output-to-sequence</code></a>
+ <li><a href="#in-memory-stream-error"><code>in-memory-stream-error</code></a>
+ <li><a href="#in-memory-stream-closed-error"><code>in-memory-stream-closed-error</code></a>
+ </ol>
+ <li><a href="#strings">Strings</a>
+ <ol>
+ <li><a href="#string-to-octets"><code>string-to-octets</code></a>
+ <li><a href="#octets-to-string"><code>octets-to-string</code></a>
+ </ol>
+ </ol>
+ <li><a href="#position">File positions</a>
+ <li><a href="#ack">Acknowledgements</a>
+</ol>
+
+<br> <br><h3><a name="example" class=none>Example usage</a></h3>
+
+The examples were created with <a href="http://www.lispworks.com/">LispWorks</a> 4.4.6 pro on Windows. The following two functions create <a href="foo.txt">the same file</a>:
+
+<pre>
+(defun foo (pathspec)
+ "With standard LispWorks streams."
+ (with-open-file (out pathspec
+ :direction :output
+ :if-exists :supersede
+ :external-format '(:utf-8 :eol-style :crlf))
+ (write-line "ÄÖÜ1" out))
+ (with-open-file (out pathspec
+ :direction :output
+ :if-exists :append
+ :external-format '(:latin-1 :eol-style :lf))
+ (write-line "ÄÖÜ2" out))
+ (with-open-file (out pathspec
+ :direction :output
+ :if-exists :append
+ :element-type 'octet)
+ (write-byte #xeb out)
+ (write-sequence #(#xa3 #xa4 #xa5) out))
+ (with-open-file (out pathspec
+ :direction :output
+ :if-exists :append
+ :external-format '(:unicode :little-endian nil :eol-style :crlf))
+ (write-line "ÄÖÜ3" out)))
+
+(defun bar (pathspec)
+ "With a <a href="#flexi-streams" class=noborder>flexi stream</a>."
+ (with-open-file (out pathspec
+ :direction :output
+ :if-exists :supersede
+ :external-format '(:latin-1 :eol-style :lf))
+ (setq out (<a href="#make-flexi-stream" class=noborder>make-flexi-stream</a> out <a href="#external-formats" class=noborder>:external-format</a> :utf-8))
+ (write-line "ÄÖÜ1" out)
+ (setf (<a href="#flexi-stream-external-format" class=noborder>flexi-stream-external-format</a> out) '(:latin-1 :eol-style :lf))
+ (write-line "ÄÖÜ2" out)
+ (write-byte #xeb out)
+ (write-sequence #(#xa3 #xa4 #xa5) out)
+ (setf (flexi-stream-external-format out) :ucs-2be)
+ (write-line "ÄÖÜ3" out)))
+</pre>
+
+<p>
+And applying this function
+<pre>
+(defun baz (pathspec)
+ (let (result)
+ (with-open-file (in pathspec :element-type '<a href="#octet" class=noborder>octet</a>)
+ (setq in (<a href="#make-flexi-stream" class=noborder>make-flexi-stream</a> in <a href="#external-formats" class=noborder>:external-format</a> :utf-8))
+ (push (read-line in) result)
+ (push (read-byte in) result)
+ (setf (<a href="#flexi-stream-external-format" class=noborder>flexi-stream-external-format</a> in) '(:latin-1 :eol-style :lf))
+ (push (read-line in) result)
+ (setf (flexi-stream-external-format in) :greek)
+ (push (read-char in) result)
+ (setf (flexi-stream-external-format in) :latin0)
+ (let ((string (make-string 3 :element-type 'character)))
+ (read-sequence string in)
+ (push string result))
+ (let ((octets (make-array 2 :element-type 'octet)))
+ (read-sequence octets in)
+ (push octets result))
+ (setf (flexi-stream-external-format in) :ucs-2be)
+ (push (read-line in) result))
+ (nreverse result)))
+</pre>
+to the file created above will yield the list
+<pre>
+("ÄÖÜ1" 196 "ÖÜ2" #\λ "£€¥" #(0 196) "ÖÜ3")
+</pre>
+
+<p>
+For more examples see the source code
+of <a
+href="http://weitz.de/drakma/">Drakma</a>, <a
+href="http://weitz.de/chunga/">Chunga</a>,
+or <a href="http://weitz.de/cl-wbxml/">CL-WBXML</a>.
+
+<br> <br><h3><a name="install" class=none>Download and installation</a></h3>
+
+Before you try to install FLEXI-STREAMS, first check that in your Lisp
+each <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/13_.htm">character</a>'s
+<a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#characte…">character
+code</a> is equal to
+its <a
+href="http://en.wikipedia.org/wiki/Unicode">Unicode</a> <a
+href="http://unicode.org/glossary/">code point</a> and
+that <code>(CHAR-CODE #\Newline)</code>
+and <code>(CHAR-CODE #\Linefeed)</code> have the same
+value (10). (This is the case for all relevant CL
+implementations which were in use when this library was written. It
+is <em>not</em> mandated by the ANSI standard, though.)
+<p>
+FLEXI-STREAMS together with this documentation can be downloaded from <a
+href="http://weitz.de/files/flexi-streams.tar.gz">http://weitz.de/files/flexi-streams.tar.gz</a>. The
+current version is 0.13.1.
+<p>
+Before you install FLEXI-STREAMS you first need to
+install the <a
+href="http://www.cliki.net/trivial-gray-streams">trivial-gray-streams</a> library
+unless you already have it.
+<p>
+FLEXI-STREAMS comes with a system definition for <a
+href="http://www.cliki.net/asdf">ASDF</a> so you can install the library with
+<pre>
+(asdf:oos 'asdf:load-op :flexi-streams)
+</pre>
+if you've unpacked it in a place where ASDF can find it. Installation
+via <a href="http://www.cliki.net/asdf-install">asdf-install</a>
+should also be possible, and there's a port
+to <a href="http://www.cliki.net/Gentoo">Gentoo Lisp</a> thanks to
+Matthew Kennedy.
+<p>
+You can run a test suite which tests <em>some</em> (but
+not <em>all</em>) aspects of the library with
+<pre>
+(asdf:oos 'asdf:test-op :flexi-streams)
+</pre>
+This might take a while...
+<p>
+Luís Oliveira maintains a <a href="http://darcs.net/">darcs</a>
+repository of FLEXI-STREAMS
+at <a href="http://common-lisp.net/%7Eloliveira/ediware/">http://common-lisp.net/~loliveira/ediware/</a>.
+<p>
+A <a href="http://www.selenic.com/mercurial/wiki/">Mercurial</a>
+repository of older versions is available
+at <a
+href="http://arcanes.fr.eu.org/~pierre/2007/02/weitz/">http://arcanes.fr.eu.org/~pierre/2007/02/weitz/</a>
+thanks to Pierre Thierry.
+
+<!-- this chapter may be removed after several versions -->
+<br> <br>
+<h3><a name="backward-compatibility" class=none>
+Backward compatibility with version 0.10.3 and before</a></h3>
+
+Two special variables used in flexi-streams 0.10.3 and before were removed -
+<code>*PROVIDE-USE-VALUE-RESTART*</code> and <code>*USE-REPLACEMENT-CHAR*</code>.
+
+<p>
+The code now behaves as if
+<code>*PROVIDE-USE-VALUE-RESTART*</code> is always <code>T</code>.
+Instead of <code>*USE-REPLACEMENT-CHAR*</code>, you can use
+<a href="#*substitution-char*"><code>*SUBSTITUTION-CHAR*</code></a> or
+invoke
+a <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/r_use_va.htm"><code>USE-VALUE</code>
+restart</a>
+when a <a
+href="#flexi-stream-encoding-error"><code>FLEXI-STREAM-ENCODING-ERROR</code></a>
+is signaled.
+
+<br> <br><h3><a name="mail" class=none>Support and mailing lists</a></h3>
+
+For questions, bug reports, feature requests, improvements, or patches
+please use the <a
+href="http://common-lisp.net/mailman/listinfo/flexi-streams-devel">flexi-streams-devel
+mailing list</a>. If you want to be notified about future releases,
+subscribe to the <a
+href="http://common-lisp.net/mailman/listinfo/flexi-streams-announce">flexi-streams-announce
+mailing list</a>. These mailing lists were made available thanks to
+the services of <a href="http://common-lisp.net/">common-lisp.net</a>.
+<p>
+If you want to send patches, please <a href="http://weitz.de/patches.html">read this first</a>.
+
+
+<br> <br><h3><a class=none name="dictionary">The FLEXI-STREAMS dictionary</a></h3>
+
+<h4><a name="external-formats" class=none>External formats</a></h4>
+
+<code>EXTERNAL-FORMAT</code> objects are used to denote the external
+formats of <a href="#flexi-streams">flexi streams</a>. These objects are created using
+the <a
+href="#make-external-format"><code>MAKE-EXTERNAL-FORMAT</code></a>
+function, and there are <a href="#external-format-name">various
+readers</a> to query their attributes. Once such an object is
+created it can't be changed.
+<p>
+An external format consists of a basic encoding
+(like <a
+href="http://en.wikipedia.org/wiki/Iso-8859-1">ISO 8859-1</a>
+or <a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8</a>), a
+definition how line endings are denoted - by a carriage return
+character (ASCII 13), by a line feed character (ASCII 10),
+or by both of these characters in a row -, and optionally (for
+encodings that use units larger than 8 bits) information
+about the <a href="http://en.wikipedia.org/wiki/Endian">endianess</a>
+of the encoding.
+<p>
+The following encodings are currently supported by FLEXI-STREAMS:
+<ul>
+<li><a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8</a> (denoted by the keyword <code>:UTF-8</code>),
+<li><a href="http://en.wikipedia.org/wiki/UTF-16">UTF-16</a> (denoted by the keyword <code>:UTF-16</code>),
+<li><a href="http://en.wikipedia.org/wiki/UTF-32">UTF-32</a> (denoted by the keyword <code>:UTF-32</code>),
+<li>all <a href="http://czyborra.com/charsets/iso8859.html">ISO 8859</a> character sets (denoted by keywords like <code>:ISO-8859-15</code>),
+<li><a href="http://en.wikipedia.org/wiki/KOI8-R">KOI8-R</a> (denoted by the keyword <code>:KOI8-R</code>),
+<li>a couple
+of <a href="http://czyborra.com/charsets/codepages.html">Windows code
+pages</a> (denoted by the keyword <code>:CODE-PAGE</code> and an
+obligatory <code>:ID</code> argument), and
+<li><a href="http://en.wikipedia.org/wiki/ASCII">US-ASCII</a>.
+</ul>
+<p>
+A couple of alternative names are allowed that are listed below:
+<p>
+<table border=1>
+<tr><td><code>:UTF-8</code></td><td><code>:UTF8</code></td></tr>
+<tr><td rowspan=4 valign=top><code>:UTF-16</code></td><td><code>:UTF16</code></td></tr>
+<tr><td><code>:UCS-2</code></td></tr>
+<tr><td><code>:UCS2</code></td></tr>
+<tr><td><code>:UNICODE</code></td></tr>
+<tr><td rowspan=3 valign=top><code>:UTF-32</code></td><td><code>:UTF32</code></td></tr>
+<tr><td><code>:UCS-4</code></td></tr>
+<tr><td><code>:UCS4</code></td></tr>
+<tr><td rowspan=2 valign=top><code>:ISO-8859-1</code></td><td><code>:LATIN-1</code></td></tr>
+<tr><td><code>:LATIN1</code></td></tr>
+<tr><td rowspan=2 valign=top><code>:ISO-8859-2</code></td><td><code>:LATIN-2</code></td></tr>
+<tr><td><code>:LATIN2</code></td></tr>
+<tr><td rowspan=2 valign=top><code>:ISO-8859-3</code></td><td><code>:LATIN-3</code></td></tr>
+<tr><td><code>:LATIN3</code></td></tr>
+<tr><td rowspan=2 valign=top><code>:ISO-8859-4</code></td><td><code>:LATIN-4</code></td></tr>
+<tr><td><code>:LATIN4</code></td></tr>
+<tr><td><code>:ISO-8859-5</code></td><td><code>:CYRILLIC</code></td></tr>
+<tr><td><code>:ISO-8859-6</code></td><td><code>:ARABIC</code></td></tr>
+<tr><td><code>:ISO-8859-7</code></td><td><code>:GREEK</code></td></tr>
+<tr><td><code>:ISO-8859-8</code></td><td><code>:HEBREW</code></td></tr>
+<tr><td rowspan=2 valign=top><code>:ISO-8859-9</code></td><td><code>:LATIN-5</code></td></tr>
+<tr><td><code>:LATIN5</code></td></tr>
+<tr><td rowspan=2 valign=top><code>:ISO-8859-10</code></td><td><code>:LATIN-6</code></td></tr>
+<tr><td><code>:LATIN6</code></td></tr>
+<tr><td><code>:ISO-8859-11</code></td><td><code>:THAI</code></td></tr>
+<tr><td rowspan=2 valign=top><code>:ISO-8859-13</code></td><td><code>:LATIN-7</code></td></tr>
+<tr><td><code>:LATIN7</code></td></tr>
+<tr><td rowspan=2 valign=top><code>:ISO-8859-14</code></td><td><code>:LATIN-8</code></td></tr>
+<tr><td><code>:LATIN8</code></td></tr>
+<tr><td rowspan=4 valign=top><code>:ISO-8859-15</code></td><td><code>:LATIN-9</code></td></tr>
+<tr><td><code>:LATIN9</code></td></tr>
+<tr><td><code>:LATIN-0</code></td></tr>
+<tr><td><code>:LATIN0</code></td></tr>
+<tr><td rowspan=2 valign=top><code>:ISO-8859-16</code></td><td><code>:LATIN-10</code></td></tr>
+<tr><td><code>:LATIN10</code></td></tr>
+<tr><td rowspan=2 valign=top><code>:CODE-PAGE</code></td><td><code>:CODEPAGE</code></td></tr>
+<tr><td><code>WIN32:CODE-PAGE<br>(only on <a href="http://www.lispworks.com/products/lww.html">LWW</a>)</code></td></tr>
+<tr><td><code>:KOI8-R</code></td><td><code>:KOI8R</code></td></tr>
+<tr><td><code>:US-ASCII</code></td><td><code>:ASCII</code></td></tr>
+</table>
+<p>
+(Note that we treat UCS-2 exactly like UTF-16 although there
+are <a href="http://en.wikipedia.org/wiki/UTF-16">subtle
+differences</a>. Also note that even though we support encodings like
+UTF-32 some Lisps only supports characters contained within
+the <a
+href="http://en.wikipedia.org/wiki/Basic_Multilingual_Plane">Basic
+Multilingual Plane</a> (like LispWorks) or even less (like CMUCL), so
+if other characters are read from a
+<a href="#flexi-streams">flexi
+stream</a>, <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_cha.htm"><code>READ-CHAR</code></a>
+will try to be helpful and return the corresponding Unicode code point -
+an integer - instead. This might lead to an error if you're using
+functions
+like <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_lin.htm"><code>READ-LINE</code></a>, though.)
+
+<p>
+Whenever a FLEXI-STREAMS function accepts an external format as one of
+its arguments, you can provide either an <code>EXTERNAL-FORMAT</code>
+object or a shortcut which can be a list or a symbol. The list
+shortcuts have a syntax similar
+to <a
+href="http://www.lispworks.com/documentation/lw50/LWUG/html/lwuser-360.htm">the
+one used by LispWorks</a> - the cars are the names of and encoding
+and the cdrs of these lists correspond to the keyword arguments
+to <a
+href="#make-external-format"><code>MAKE-EXTERNAL-FORMAT</code></a>, so
+for example
+<pre>(:latin-1 :eol-style :crlf)</pre>
+is equivalent to
+<pre>(<a class=noborder href="#make-external-format">make-external-format</a> :latin-1 :eol-style :crlf)</pre> The
+symbol shortcuts are equivalent to
+calling <a
+href="#make-external-format"><code>MAKE-EXTERNAL-FORMAT</code></a>
+without keyword arguments, i.e.
+<pre>:thai</pre>
+behaves like
+<pre>(<a class=noborder href="#make-external-format">make-external-format</a> :thai)</pre>
+Finally, the following expansions are
+available:
+<p>
+<table border=1>
+<tr><td><code>:UCS-2LE</code></td><td><code>(:UCS-2 :LITTLE-ENDIAN T)</code></td></tr>
+<tr><td><code>:UCS-2BE</code></td><td><code>(:UCS-2 :LITTLE-ENDIAN NIL)</code></td></tr>
+<tr><td><code>:UCS-4LE</code></td><td><code>(:UCS-4 :LITTLE-ENDIAN T)</code></td></tr>
+<tr><td><code>:UCS-4BE</code></td><td><code>(:UCS-4 :LITTLE-ENDIAN NIL)</code></td></tr>
+<tr><td><code>:UTF-16LE</code></td><td><code>(:UTF-16 :LITTLE-ENDIAN T)</code></td></tr>
+<tr><td><code>:UTF-16BE</code></td><td><code>(:UTF-16 :LITTLE-ENDIAN NIL)</code></td></tr>
+<tr><td><code>:UTF-32LE</code></td><td><code>(:UTF-32 :LITTLE-ENDIAN T)</code></td></tr>
+<tr><td><code>:UTF-32BE</code></td><td><code>(:UTF-32 :LITTLE-ENDIAN NIL)</code></td></tr>
+<tr><td><code>:IBM437</code></td><td><code>(:CODE-PAGE :ID 437)</code></td></tr>
+<tr><td><code>:IBM850</code></td><td><code>(:CODE-PAGE :ID 850)</code></td></tr>
+<tr><td><code>:IBM852</code></td><td><code>(:CODE-PAGE :ID 852)</code></td></tr>
+<tr><td><code>:IBM855</code></td><td><code>(:CODE-PAGE :ID 855)</code></td></tr>
+<tr><td><code>:IBM857</code></td><td><code>(:CODE-PAGE :ID 857)</code></td></tr>
+<tr><td><code>:IBM860</code></td><td><code>(:CODE-PAGE :ID 860)</code></td></tr>
+<tr><td><code>:IBM861</code></td><td><code>(:CODE-PAGE :ID 861)</code></td></tr>
+<tr><td><code>:IBM862</code></td><td><code>(:CODE-PAGE :ID 862)</code></td></tr>
+<tr><td><code>:IBM863</code></td><td><code>(:CODE-PAGE :ID 863)</code></td></tr>
+<tr><td><code>:IBM864</code></td><td><code>(:CODE-PAGE :ID 864)</code></td></tr>
+<tr><td><code>:IBM865</code></td><td><code>(:CODE-PAGE :ID 865)</code></td></tr>
+<tr><td><code>:IBM866</code></td><td><code>(:CODE-PAGE :ID 866)</code></td></tr>
+<tr><td><code>:IBM869</code></td><td><code>(:CODE-PAGE :ID 869)</code></td></tr>
+<tr><td><code>:WINDOWS-1250</code></td><td><code>(:CODE-PAGE :ID 1250)</code></td></tr>
+<tr><td><code>:WINDOWS-1251</code></td><td><code>(:CODE-PAGE :ID 1251)</code></td></tr>
+<tr><td><code>:WINDOWS-1252</code></td><td><code>(:CODE-PAGE :ID 1252)</code></td></tr>
+<tr><td><code>:WINDOWS-1253</code></td><td><code>(:CODE-PAGE :ID 1253)</code></td></tr>
+<tr><td><code>:WINDOWS-1254</code></td><td><code>(:CODE-PAGE :ID 1254)</code></td></tr>
+<tr><td><code>:WINDOWS-1255</code></td><td><code>(:CODE-PAGE :ID 1255)</code></td></tr>
+<tr><td><code>:WINDOWS-1256</code></td><td><code>(:CODE-PAGE :ID 1256)</code></td></tr>
+<tr><td><code>:WINDOWS-1257</code></td><td><code>(:CODE-PAGE :ID 1257)</code></td></tr>
+<tr><td><code>:WINDOWS-1258</code></td><td><code>(:CODE-PAGE :ID 1258)</code></td></tr>
+</table>
+<p>
+Note that if you provide a shortcut, it
+will be converted to an <code>EXTERNAL-FORMAT</code> object first.
+So, if you're concerned about efficiency, create these objects once and
+re-use them.
+
+<p><br>[Function]
+<br><a class=none name="make-external-format"><b>make-external-format</b> <i>name <tt>&key</tt> eol-style little-endian id</i> => <i>external-format</i></a>
+
+<blockquote><br> Creates and returns
+an <a href="#external-formats"><code>EXTERNAL-FORMAT</code>
+object</a>. <code><i>name</i></code> is a
+symbol, <code><i>eol-style</i></code> is one of the
+keywords <code>:CR</code>, <code>:LF</code>, or <code>:CRLF</code>,
+and <code><i>little-endian</i></code> is
+a <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_g.htm#generali…">generalized
+boolean</a>. The default value for <code><i>eol-style</i></code> is the value of <a href="#*default-eol-style*"><code>*DEFAULT-EOL-STYLE*</code></a> except for Windows code pages where it is <code>:CRLF</code>. The default value
+for <code><i>little-endian</i></code> is the value of <a href="#*default-little-endian*"><code>*DEFAULT-LITTLE-ENDIAN*</code></a> - this value is ignored unless <code><i>name</i></code> denotes one of UTF-16 or UTF-32.
+<code><i>id</i></code> must be an integer denoting a Windows code page
+known by FLEXI-STREAMS if <code><i>name</i></code>
+is <code>:CODE-PAGE</code> or <code>WIN32:CODE-PAGE</code>, otherwise
+the value is ignored. See <a href="#external-formats">the section
+about external formats</a> for more info.
+<p>
+Examples (run on Windows):
+
+<pre>
+CL-USER 1 > (make-external-format :latin-1)
+#<FLEXI-STREAMS::EXTERNAL-FORMAT (:ISO-8859-1 :EOL-STYLE :CRLF) 2067DA84>
+
+CL-USER 2 > (make-external-format :latin-1 :eol-style :lf)
+#<FLEXI-STREAMS::EXTERNAL-FORMAT (:ISO-8859-1 :EOL-STYLE :LF) 2068B4D4>
+
+CL-USER 3 > (make-external-format :ibm437)
+#<FLEXI-STREAMS::EXTERNAL-FORMAT (:CODE-PAGE :ID 437 :EOL-STYLE :CRLF) 2069B33C>
+
+CL-USER 4 > (make-external-format :ucs-2)
+#<FLEXI-STREAMS::EXTERNAL-FORMAT (:UTF-16 :EOL-STYLE :CRLF :LITTLE-ENDIAN T) 206B4F4C>
+
+CL-USER 5 > (make-external-format :ucs-2be)
+#<FLEXI-STREAMS::EXTERNAL-FORMAT (:UTF-16 :EOL-STYLE :CRLF :LITTLE-ENDIAN NIL) 2067DBE4>
+
+CL-USER 6 > (make-external-format :ucs-2be :eol-style :br)
+#<FLEXI-STREAMS::EXTERNAL-FORMAT (:UTF-16 :EOL-STYLE :BR :LITTLE-ENDIAN NIL) 206B54AC>
+</pre>
+</blockquote>
+
+<p><br>[Readers]
+<br><a class=none name="external-format-name"><b>external-format-name</b> <i>external-format</i> => <i>name</i></a>
+<br><a class=none name="external-format-eol-style"><b>external-format-eol-style</b> <i>external-format</i> => <i>eol-style</i></a>
+<br><a class=none name="external-format-little-endian"><b>external-format-little-endian</b> <i>external-format</i> => <i>little-endian</i></a>
+<br><a class=none name="external-format-id"><b>external-format-id</b> <i>external-format</i> => <i>id</i></a>
+
+<blockquote><br>
+These methods can be used to query an <a href="#external-formats"><code>EXTERNAL-FORMAT</code> object</a> for its attributes.
+</blockquote>
+
+<p><br>[Functions]
+<br><a class=none name="external-format-equal"><b>external-format-equal</b> <i>external-format-1 external-format-2</i> => <i>generalized-boolean</i></a>
+
+<blockquote><br>
+Checks whether the two <a href="#external-formats">external formats</a> <code><i>external-format-1</i></code> and <code><i>external-format-2</i></code> are equivalent with respect to their effects on <a href="#flexi-streams">flexi streams</a>.
+<p>
+Examples (run on Windows):
+
+<pre>
+CL-USER 1 > (<a href="#make-external-format" class=noborder>make-external-format</a> :ucs-4le)
+#<FLEXI-STREAMS::EXTERNAL-FORMAT (:UTF-32 :EOL-STYLE :CRLF :LITTLE-ENDIAN T) 2067FB74>
+
+CL-USER 2 > (external-format-equal <a href="http://www.lispworks.com/documentation/HyperSpec/Body/v__stst_.htm" class=noborder>*</a> (make-external-format :utf32 :little-endian t))
+T
+
+CL-USER 3 > (make-external-format :code-page :id 437)
+#<FLEXI-STREAMS::EXTERNAL-FORMAT (:CODE-PAGE :ID 437 :EOL-STYLE :CRLF) 2069428C>
+
+CL-USER 4 > (external-format-equal * (make-external-format :ibm437))
+T
+</pre>
+
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*default-eol-style*"><b>*default-eol-style*</b></a>
+
+<blockquote><br>
+The default value for the <code><i>eol-style</i></code> keyword argument of <a href="#make-external-format"><code>MAKE-EXTERNAL-FORMAT</code></a>. Its initial value is <code>:CRLF</code> on Windows and <code>:LF</code> on other operating systems.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*default-little-endian*"><b>*default-little-endian*</b></a>
+
+<blockquote><br>
+The default value for the <code><i>little-endian</i></code> keyword argument of <a href="#make-external-format"><code>MAKE-EXTERNAL-FORMAT</code></a>. Its initial value corresponds to the endianess of the platform FLEXI-STREAMS is used on as revealed by the <code>:LITTLE-ENDIAN</code> <a href="http://www.lispworks.com/documentation/HyperSpec/Body/24_ab.htm">feature</a>.
+</blockquote>
+
+<h4><a name="flexi-streams" class=none>Flexi streams</a></h4>
+
+<em>Flexi streams</em> are the core of the FLEXI-STREAMS library. You
+create them using the
+function <a
+href="#make-flexi-stream"><code>MAKE-FLEXI-STREAM</code></a> which
+takes an open binary stream (called the <em>underlying</em> stream) as its only required argument.
+A <em>binary</em> stream in this context means that if it's an <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_i.htm#input">input
+stream</a>, you can read from it with
+<a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_by.htm"><code>READ-BYTE</code></a>
+(or, as a workaround for LispWorks, you can at least apply
+<a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_seq.htm"><code>READ-SEQUENCE</code></a>
+to it where the sequence is an array of element
+type <a href="#octet"><code>OCTET</code></a>), and similarly for
+<a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_wr_by.htm#write-byte"><code>WRITE-BYTE</code></a>
+(<a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_wr_seq.htm"><code>WRITE-SEQUENCE</code></a>
+for LispWorks)
+and <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_o.htm#output">output
+streams</a>. (Note that this specifically holds
+for <a
+href="http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-91.htm"><em>bivalent</em>
+streams</a> like socket streams.)
+<p>
+A flexi stream behaves like an ordinary Lisp stream. It is an input
+stream if the underlying binary stream is an input stream, and it is
+an output stream when the underlying binary stream is an output
+stream. You can write characters as well
+as <a href="#octet">octets</a> to an output flexi stream and similarly
+you can read characters and octets from an input flexi stream.
+<p>
+A flexi stream always has an <a href="#external-formats">external
+format</a> associated with it which is deployed whenever you read
+characters from the stream or write characters to it. You
+can <a href="#flexi-stream-external-format">change</a> the external
+format while you use the stream.
+<p>
+Once you're using a flexi stream you should <em>not</em> read from or
+write to the underlying stream directly anymore.
+<p>
+If
+you <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_close.htm">close</a>
+a flexi stream, the underlying stream will also be closed. However, it
+also suffices to close the underlying stream directly should you not
+want to use the flexi stream anymore. So, the following usage
+(where <code>IN</code> is implicitly closed at the end) is OK:
+<pre>
+(with-open-file (in "/foo/bar/baz.txt")
+ (let ((flexi (<a href="#make-flexi-stream" class=noborder>make-flexi-stream</a> in <a href="#external-formats" class=noborder>:external-format</a> :hebrew)))
+ (read-line flexi)))
+</pre>
+<p>
+Output flexi streams will try to keep track of
+the <a
+href="http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-591.htm">column</a>
+they're in but you can also <a href="#flexi-stream-column">set</a> the
+column directly. This value will be incremented by one for each
+character written to the stream and it will be set to <code>0</code>
+if you send a <code>#\Newline</code> character. The column will be
+set to <code>NIL</code> if an <a href="#octet"><code>OCTET</code></a>
+is sent to the stream. Once the column is <code>NIL</code> it'll stay
+like that unless it is explicitly set to another value.
+<p>
+Input flexi streams keep track of
+their <a href="#flexi-stream-position">position</a> within the stream.
+This value is incremented by one for
+each <a href="#octet"><code>OCTET</code></a> read from the stream, and
+it is incremented by the number of octets actually read for each
+character read from the stream. So, if the encoding is UTF-8, reading
+the character <code>#\ä</code> (a-umlaut) will advance the position by two.
+If the encoding is UTF-32 and the end-of-line style
+is <code>:CRLF</code>, reading a <code>#\Newline</code> will advance
+the position by eight.
+<p>
+You can also set the <a href="#flexi-stream-bound">bound</a> of an
+input flexi stream. Initially it is <code>NIL</code>, but when it's
+an integer and the
+stream's <a href="#flexi-stream-position">position</a> has gone beyond
+this bound, the stream will behave as if no more input is available.
+<p>
+Caveat: You can
+only <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_unrd_c.htm">unread</a>
+a character from a flexi stream if you haven't changed the external format after you read it.
+<p>
+Caveat: The <em>underlying</em> stream should either be a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_b.htm#binary">binary stream</a> (i.e. have an element type that is a subtype of integer) or it should explicitly use an <a href="http://www.lispworks.com/documentation/lw50/LWUG/html/lwuser-360.htm">external format</a> with <code>:LF</code> as its end-of-line style. Otherwise it might perform unwanted conversion of line endings on its own. (LispWorks <a href="http://article.gmane.org/gmane.lisp.lispworks.general/4859">does this</a> even if you write binary data to the stream using <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_wr_seq.htm"><code>WRITE-SEQUENCE</code></a>.)
+
+<p><br>[Standard class]
+<br><a class=none name="flexi-stream"><b>flexi-stream</b></a>
+
+<blockquote><br>
+Every <a href="#flexi-streams"><em>flexi stream</em></a> returned by <a href="#make-flexi-stream"><code>MAKE-FLEXI-STREAM</code></a> is of this type which is a subtype of <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_stream.htm"><code>STREAM</code></a>.
+</blockquote>
+
+<p><br>[Standard class]
+<br><a class=none name="flexi-input-stream"><b>flexi-input-stream</b></a>
+
+<blockquote><br>
+A <a href="#flexi-streams"><em>flexi stream</em></a> is of this type if its underlying stream is an <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_in_stm.htm">input stream</a>. This is a subtype of <a href="#flexi-stream"><code>FLEXI-STREAM</code></a>.
+</blockquote>
+
+<p><br>[Standard class]
+<br><a class=none name="flexi-output-stream"><b>flexi-output-stream</b></a>
+
+<blockquote><br>
+A <a href="#flexi-streams"><em>flexi stream</em></a> is of this type if its underlying stream is an <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_in_stm.htm">output stream</a>. This is a subtype of <a href="#flexi-stream"><code>FLEXI-STREAM</code></a>.
+</blockquote>
+
+<p><br>[Standard class]
+<br><a class=none name="flexi-io-stream"><b>flexi-io-stream</b></a>
+
+<blockquote><br>
+A <a href="#flexi-streams"><em>flexi stream</em></a> is of this type if it is both a <a href="#flexi-input-stream"><code>FLEXI-INPUT-STREAM</code></a> as well as a <a href="#flexi-output-stream"><code>FLEXI-OUTPUT-STREAM</code></a>.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="make-flexi-stream"><b>make-flexi-stream</b> <i>stream <tt>&key</tt> external-format element-type column position bound</i> => <i>flexi-stream</i></a>
+
+<blockquote><br>
+Creates and returns a <a href="#flexi-streams"><em>flexi stream</em></a>, i.e. an object of type <a href="#flexi-stream"><code>FLEXI-STREAM</code></a>. <code><i>stream</i></code> is the underlying Lisp stream. <code><i>external-format</i></code> is the initial <a href="#external-formats">external format</a> to be used by the stream, the default is the value of evaluating <code>(<a href="#make-external-format">MAKE-EXTERNAL-FORMAT</a> :LATIN1)</code>. <code><i>element-type</i></code> is the initial <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_stm_el.htm">element type</a> of the flexi stream the default of which is <a href="http://www.lispworks.com/documentation/lw50/LWRM/html/lwref-346.htm"><code>LW:SIMPLE-CHAR</code></a> for LispWorks and <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_ch.htm"><code>CHARACTER</code></a> otherwise. <code><i>column</i></code> is the initial column of the stream and should only be provided for output streams, the default is <code>0</code>. <code><i>position</i></code> is the initial octet position of the stream and must only be provided for input streams, the default is <code>0</code>. <code><i>bound</i></code> should be <code>NIL</code> (the default) or an integer and must only be provided for input streams. If the octet position of the stream has gone beyond this bound, the stream will behave as if no more input is available. See <a href="#flexi-streams">the section about flexi streams</a> for more information.
+</blockquote>
+
+<p><br>[Accessors]
+<br><a class=none name="flexi-stream-external-format"><b>flexi-stream-external-format</b> <i>flexi-stream</i> => <i>external-format</i></a>
+<br><tt>(setf (</tt><b>flexi-stream-external-format</b> <i>flexi-stream</i>) <i>external-format</i><tt>)</tt>
+<br><a class=none name="flexi-stream-element-type"><b>flexi-stream-element-type</b> <i>flexi-stream</i> => <i>element-type</i></a>
+<br><tt>(setf (</tt><b>flexi-stream-element-type</b> <i>flexi-stream</i>) <i>element-type</i><tt>)</tt>
+<br><a class=none name="flexi-stream-column"><b>flexi-stream-column</b> <i>flexi-output-stream</i> => <i>column</i></a>
+<br><tt>(setf (</tt><b>flexi-stream-column</b> <i>flexi-output-stream</i>) <i>column</i><tt>)</tt>
+<br><a class=none name="flexi-stream-position"><b>flexi-stream-position</b> <i>flexi-input-stream</i> => <i>position</i></a>
+<br><tt>(setf (</tt><b>flexi-stream-position</b> <i>flexi-input-stream</i>) <i>position</i><tt>)</tt>
+<br><a class=none name="flexi-stream-bound"><b>flexi-stream-bound</b> <i>flexi-input-stream</i> => <i>bound</i></a>
+<br><tt>(setf (</tt><b>flexi-stream-bound</b> <i>flexi-input-stream</i>) <i>bound</i><tt>)</tt>
+
+<blockquote><br>
+These methods can be used to get and set the corresponding attributes of a <a href="#flexi-streams">flexi stream</a>.
+<p>
+<a href="#flexi-stream-external-format"><code>(SETF
+FLEXI-STREAM-EXTERNAL-FORMAT)</code></a> accepts keyword symbols
+(<a href="#external-formats">names of external formats</a>), lists
+(which should be valid lists of parameters
+to <a
+href="#make-external-format"><code>MAKE-EXTERNAL-FORMAT</code></a>), or <code>EXTERNAL-FORMAT</code> objects:
+<pre>
+CL-USER 1 > (setf (flexi-stream-external-format *my-stream*) :ucs-4le)
+#<FLEXI-STREAMS::EXTERNAL-FORMAT (:UTF-32 :EOL-STYLE :CRLF :LITTLE-ENDIAN T) 206920DC>
+
+CL-USER 2 > (setf (flexi-stream-external-format *my-stream*) '(:ucs-2be :eol-style :br))
+#<FLEXI-STREAMS::EXTERNAL-FORMAT (:UTF-16 :EOL-STYLE :BR :LITTLE-ENDIAN NIL) 20696934>
+
+CL-USER 3 > (setf (flexi-stream-external-format *my-stream*) (make-external-format :ibm437))
+#<FLEXI-STREAMS::EXTERNAL-FORMAT (:CODE-PAGE :ID 437 :EOL-STYLE :CRLF) 2068716C>
+</pre>
+</blockquote>
+
+<p><br>[Reader]
+<br><a class=none name="flexi-stream-stream"><b>flexi-stream-stream</b> <i>flexi-stream</i> => <i>stream</i></a>
+
+<blockquote><br>
+This method returns the underlying stream of a <a href="#flexi-streams">flexi stream</a>.
+</blockquote>
+
+<p><br>[Generic function]
+<br><a class=none name="unread-byte"><b>unread-byte</b> <i>byte stream</i> => <i>nil</i></a>
+
+<blockquote><br>
+Similar to <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_unrd_c.htm"><code>UNREAD-CHAR</code></a> in that it "unreads" the last <a href="#octet">octet</a> from
+<code><i>stream</i></code> which must be a <a href="#flexi-streams">flexi stream</a>. Note that you can only call <code>UNREAD-BYTE</code> after a corresponding
+<a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_by.htm"><code>READ-BYTE</code></a>, <em>not</em> after <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_rd_cha.htm"><code>READ-CHAR</code></a>.
+</blockquote>
+
+<p><br>[Generic function]
+<br><a class=none name="peek-byte"><b>peek-byte</b> <i>stream <tt>&optional</tt> peek-type eof-error-p eof-value</i> => <i>byte</i></a>
+
+<blockquote><br>
+<code>PEEK-BYTE</code> is like <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_peek_c.htm"><code>PEEK-CHAR</code></a>, i.e. it returns an <a href="#octet">octet</a> from <code><i>stream</i></code> (which must be a <a href="#flexi-streams">flexi stream</a>)
+without actually removing it. If <code><i>peek-type</i></code> is <code>NIL</code>, the next octet is
+returned, if <code><i>peek-type</i></code> is <code>T</code>, the next octet which is not <code>0</code> is
+returned, if <code><i>peek-type</i></code> is an octet, the next octet which equals
+<code><i>peek-type</i></code> is returned. <code><i>eof-error-p</i></code> and <code><i>eof-value</i></code> are interpreted as usual.
+<p>
+Note that the parameters aren't in the same order as with <a href="http://www.lispworks.com/documentation/HyperSpec/Body/f_peek_c.htm"><code>PEEK-CHAR</code></a> because it doesn't make much sense to make <code><i>stream</i></code> an optional argument.
+</blockquote>
+
+<p><br>[Special variable]
+<br><a class=none name="*substitution-char*"><b>*substitution-char*</b></a>
+
+<blockquote><br>
+If this value is not NIL, it should be a character which is used
+(as if by a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/r_use_va.htm"><code>USE-VALUE</code> restart</a>) whenever during reading an error of
+type <a href="#flexi-stream-encoding-error"><code>FLEXI-STREAM-ENCODING-ERROR</code></a> would have been signaled otherwise.
+
+<pre>
+CL-USER 1 > (defun foo ()
+ <font color=orange>;; not a valid UTF-8 sequence</font>
+ (<a href="#with-input-from-sequence" class=noborder>with-input-from-sequence</a> (in '(#xe4 #xf6 #xfc))
+ (setq in (<a href="#make-flexi-stream" class=noborder>make-flexi-stream</a> in :external-format :utf8))
+ (read-line in)))
+FOO
+
+CL-USER 2 > (foo)
+
+Error: Unexpected value #xF6 in UTF-8 sequence.
+ 1 (continue) Specify a character to be used instead.
+ 2 (abort) Return to level 0.
+ 3 Return to top loop level 0.
+
+Type :b for backtrace, :c <option number> to proceed, or :? for other options
+
+CL-USER 3 : 1 > :c
+Type a character: x
+
+Error: End of file while in UTF-8 sequence.
+ 1 (continue) Specify a character to be used instead.
+ 2 (abort) Return to level 0.
+ 3 Return to top loop level 0.
+
+Type :b for backtrace, :c <option number> to proceed, or :? for other options
+
+CL-USER 4 : 1 > :c
+Type a character: y
+"xy"
+T
+
+CL-USER 5 > (<a href="http://www.lispworks.com/documentation/HyperSpec/Body/m_handle.htm" class=noborder>handler-bind</a> ((<a href="#flexi-stream-encoding-error" class=noborder>flexi-stream-encoding-error</a> (lambda (condition)
+ (<a href="http://www.lispworks.com/documentation/HyperSpec/Body/r_use_va.htm" class=noborder>use-value</a> #\-))))
+ (foo))
+"--"
+T
+
+CL-USER 6 > (let ((<a href="#*SUBSTITUTION-CHAR*" class=noborder>*substitution-char*</a> #\?))
+ (foo))
+"??"
+T
+</pre>
+</blockquote>
+
+<p><br>[Type]
+<br><a class=none name="octet"><b>octet</b></a>
+
+<blockquote><br>
+Just a shortcut for <code>(UNSIGNED-BYTE 8)</code>.
+</blockquote>
+
+<p><br>[Condition]
+<br><a class=none name="flexi-stream-error"><b>flexi-stream-error</b></a>
+
+<blockquote><br>
+All errors related to <a href="#flexi-streams">flexi streams</a> are of this type. This is a subtype of <a href="http://www.lispworks.com/documentation/HyperSpec/Body/e_stm_er.htm"><code>STREAM-ERROR</code></a>.
+</blockquote>
+
+<p><br>[Condition]
+<br><a class=none name="flexi-stream-encoding-error"><b>flexi-stream-encoding-error</b></a>
+
+<blockquote><br>
+All errors related to encoding problems with <a href="#flexi-streams">flexi streams</a> are of this type. (This includes situation where an end of file is encountered in the middle of a multi-octet character.) When this condition is signaled during reading, <a href="http://www.lispworks.com/documentation/HyperSpec/Body/r_use_va.htm"><code>USE-VALUE</code>
+restart</a> is provided. See also <a href="#*substitution-char*"><code>*SUBSTITUTION-CHAR*</code></a> and example for it. <a href="#flexi-encodingstream-error"><code>FLEXI-STREAM-ENCODING-ERROR</code></a> is a subtype of <a href="#flexi-stream-error"><code>FLEXI-STREAM-ERROR</code></a>.
+</blockquote>
+
+<p><br>[Condition]
+<br><a class=none name="flexi-stream-element-type-error"><b>flexi-stream-element-type-error</b></a>
+
+<blockquote><br>
+All errors related to problems with the element type of <a href="#flexi-streams">flexi streams</a> are of this type. This is a subtype of <a href="#flexi-stream-error"><code>FLEXI-STREAM-ERROR</code></a> and has an additional slot for the element type which can be accessed with <a href="#flexi-stream-element-type-error-element-type"><code>FLEXI-STREAM-ELEMENT-TYPE-ERROR-ELEMENT-TYPE</code></a>.
+</blockquote>
+
+<p><br>[Reader]
+<br><a class=none name="flexi-stream-element-type-error-element-type"><b>flexi-stream-element-type-error-element-type</b> <i>condition</i> => <i>element-type</i></a>
+
+<blockquote><br>
+If <code><i>condition</i></code> is of type <a href="#flexi-stream-element-type-error"><code>FLEXI-STREAM-ELEMENT-TYPE-ERROR</code></a>, this function will return the offending element type.
+</blockquote>
+
+<p><br>[Condition]
+<br><a class=none name="flexi-stream-position-spec-error"><b>flexi-stream-position-spec-error</b></a>
+
+<blockquote><br> Errors of this type are signaled if an erroneous
+position spec is used in conjunction
+with <a href="#position"><code>FILE-POSITION</code></a>. This is a
+subtype
+of <a href="#flexi-stream-error"><code>FLEXI-STREAM-ERROR</code></a>
+and has an additional slot for the position spec which can be accessed
+with <a
+href="#flexi-stream-position-spec-error-position-spec"><code>FLEXI-STREAM-POSITION-SPEC-ERROR-POSITION-SPEC</code></a>.
+</blockquote>
+
+<p><br>[Reader]
+<br><a class=none name="flexi-stream-position-spec-error-position-spec"><b>flexi-stream-position-spec-error-position-spec</b> <i>condition</i> => <i>position-spec</i></a>
+
+<blockquote><br>
+If <code><i>condition</i></code> is of type <a href="#flexi-stream-position-spec-error"><code>FLEXI-STREAM-POSITION-SPEC-ERROR</code></a>, this function will return the offending position spec.
+</blockquote>
+
+<h4><a name="in-memory" class=none>In-memory streams</a></h4>
+
+The library also provides <em>in-memory</em> binary streams which are modeled after <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_stg_st.htm">string streams</a> and behave very similar only that they deal with <a href="#octet">octets</a> instead of characters and the underlying data structure is not a string but either a list or a vector. These streams can obviously be used as the underlying streams for <a href="#flexi-streams">flexi streams</a>.
+
+<p><br>[Standard class]
+<br><a class=none name="in-memory-stream"><b>in-memory-stream</b></a>
+
+<blockquote><br>
+Every <a href="#in-memory"><em>in-memory stream</em></a> returned by <a href="#make-in-memory-input-stream"><code>MAKE-IN-MEMORY-INPUT-STREAM</code></a> or <a href="#make-in-memory-output-stream"><code>MAKE-IN-MEMORY-OUTPUT-STREAM</code></a> is of this type which is a subtype of <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_stream.htm"><code>STREAM</code></a>.
+</blockquote>
+
+<p><br>[Standard class]
+<br><a class=none name="in-memory-input-stream"><b>in-memory-input-stream</b></a>
+
+<blockquote><br>
+Every <a href="#in-memory"><em>in-memory stream</em></a> returned by <a href="#make-in-memory-input-stream"><code>MAKE-IN-MEMORY-INPUT-STREAM</code></a> is of this type which is a subtype of <a href="#in-memory-stream"><code>IN-MEMORY-STREAM</code></a>.
+</blockquote>
+
+<p><br>[Standard class]
+<br><a class=none name="in-memory-output-stream"><b>in-memory-output-stream</b></a>
+
+<blockquote><br>
+Every <a href="#in-memory"><em>in-memory stream</em></a> returned by <a href="#make-in-memory-output-stream"><code>MAKE-IN-MEMORY-OUTPUT-STREAM</code></a> is of this type which is a subtype of <a href="#in-memory-stream"><code>IN-MEMORY-STREAM</code></a>.
+</blockquote>
+
+<p><br>[Standard class]
+<br><a class=none name="list-stream"><b>list-stream</b></a>
+
+<blockquote><br>
+Every <a href="#in-memory"><em>in-memory input stream</em></a> is of this type if it reads from a list.
+</blockquote>
+
+<p><br>[Standard class]
+<br><a class=none name="vector-stream"><b>vector-stream</b></a>
+
+<blockquote><br>
+Every <a href="#in-memory"><em>in-memory stream</em></a> is of this type if it reads from or writes to a vector.
+</blockquote>
+
+<p><br>[Generic function]
+<br><a class=none name="make-in-memory-input-stream"><b>make-in-memory-input-stream</b> <i>sequence <tt>&key</tt> start end transformer</i> => <i>in-memory-input-stream</i></a>
+
+<blockquote><br>
+Returns a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_b.htm#binary">binary</a> <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_i.htm#input">input</a> stream (of type <a href="#in-memory-input-stream"><code>IN-MEMORY-INPUT-STREAM</code></a>) which will supply, in order, the
+octets in the subsequence of <code><i>sequence</i></code> bounded by <code><i>start</i></code> (the default is <code>0</code>) and <code><i>end</i></code> (the default is the length of <code><i>sequence</i></code>). <code><i>sequence</i></code> must either be a list or a vector of <a href="#octet">octets</a>.
+Each octet returned will be transformed in turn by the optional
+<code><i>transformer</i></code> function.
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="make-in-memory-output-stream"><b>make-in-memory-output-stream</b> <i><tt>&key</tt> element-type transformer</i> => <i>in-memory-output-stream</i></a>
+
+<blockquote><br>
+Returns a <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_b.htm#binary">binary</a> <a href="http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_o.htm#output">output</a> stream (of type <a href="#in-memory-output-stream"><code>IN-MEMORY-OUTPUT-STREAM</code></a>) which accepts objects of type <code><i>element-type</i></code> (a subtype of <a href="#octet"><code>OCTET</code></a>) and makes
+available a sequence (see <a href="#get-output-stream-sequence"><code>GET-OUTPUT-STREAM-SEQUENCE</code></a>) that contains the octets that were actually
+output. The octets stored will each be transformed by the optional <code><i>transformer</i></code> function.
+</blockquote>
+
+<p><br>[Generic function]
+<br><a class=none name="get-output-stream-sequence"><b>get-output-stream-sequence</b> <i>stream <tt>&key</tt> as-list</i> => <i>sequence</i></a>
+
+<blockquote><br>
+Returns a vector containing, in order, all the octets that have
+been output to the <a href="#in-memory">in-memory output stream</a> <code><i>stream</i></code>. This operation clears any
+octets on <code><i>stream</i></code>, so the vector contains only those octets which have
+been output since the last call to <a href="#get-output-stream-sequence"><code>GET-OUTPUT-STREAM-SEQUENCE</code></a> or since
+the creation of the stream, whichever occurred most recently. If
+<code><i>as-list</i></code> is true the return value is coerced to a list.
+</blockquote>
+
+<p><br>[Generic function]
+<br><a class=none name="output-stream-sequence-length"><b>output-stream-sequence-length</b> <i>stream</i> => <i>length</i></a>
+
+<blockquote><br> Returns the current length of the underlying vector
+of the <a href="#in-memory">in-memory output
+stream</a> <code><i>stream</i></code>, i.e. this is the length of the
+sequence that <a href="#get-output-stream-sequence"><code>GET-OUTPUT-STREAM-SEQUENCE</code></a> would return if called at
+this very moment.
+</blockquote>
+
+<p><br>[Macro]
+<br><a class=none name="with-input-from-sequence"><b>with-input-from-sequence</b> <i>(var sequence <tt>&key</tt> start end transformer) statement*</i> => <i>result*</i></a>
+
+<blockquote><br> Creates an <a href="#in-memory">in-memory input
+stream</a> from the sequence <code><i>sequence</i></code> using the
+parameters <code><i>start</i></code> and <code><i>end</i></code>
+(see <a
+href="#make-in-memory-input-stream"><code>MAKE-IN-MEMORY-INPUT-STREAM</code></a>),
+binds <code><i>var</i></code> to this stream and then executes
+the <code><i>statement*</i></code> forms. A
+function <code><i>transformer</i></code> may optionally be specified
+to transform the returned octets. The stream is automatically closed
+on exit from
+<a href="#with-output-to-sequence"><code>WITH-OUTPUT-TO-SEQUENCE</code></a>, no matter whether the exit is normal or
+abnormal. The return value of this macro is the return value of
+the last statement of <code><i>statement*</i></code>.
+</blockquote>
+
+<p><br>[Macro]
+<br><a class=none name="with-output-to-sequence"><b>with-output-to-sequence</b> <i>(var <tt>&key</tt> as-list element-type transformer) statement*</i> => <i>sequence</i></a>
+
+<blockquote><br>
+Creates an <a href="#in-memory">in-memory output stream</a>, binds <code><i>var</i></code> to this stream and
+then executes the <code><i>statement*</i></code> forms. The stream stores
+data of type <code><i>element-type</i></code> (a subtype of <a href="#octet"><code>OCTET</code></a>) which is (optionally) transformed by the
+function <code><i>transformer</i></code> prior to storage. The stream is automatically closed on
+exit from <a href="#with-output-to-sequence"><code>WITH-OUTPUT-TO-SEQUENCE</code></a>, no matter whether the exit is
+normal or abnormal. The return value of this macro is a vector (or a
+list if <code><i>as-list</i></code> is true) containing the octets that were sent to the
+stream within the body of the macro.
+</blockquote>
+
+<p><br>[Condition]
+<br><a class=none name="in-memory-stream-error"><b>in-memory-stream-error</b></a>
+
+<blockquote><br>
+All errors related to <a href="#in-memory">in-memory streams</a> are of this type. This is a subtype of <a href="http://www.lispworks.com/documentation/HyperSpec/Body/e_stm_er.htm"><code>STREAM-ERROR</code></a>.
+</blockquote>
+
+<p><br>[Condition]
+<br><a class=none name="in-memory-stream-closed-error"><b>in-memory-stream-closed-error</b></a>
+
+<blockquote><br>
+An error of this type is signaled if one tries to read from or write to an <a href="#in-memory">in-memory stream</a> which had already been closed. This is a subtype of <a href="#in-memory-stream-error"><code>IN-MEMORY-STREAM-ERROR</code></a>.
+</blockquote>
+
+<h4><a name="strings" class=none>Strings</a></h4>
+
+This section collects a few convenience functions for strings conversions:
+
+<p><br>[Function]
+<br><a class=none name="string-to-octets"><b>string-to-octets</b> <i>string <tt>&key</tt> external-format start end</i> => <i>vector</i></a>
+
+<blockquote><br>
+
+Converts the Lisp string <code><i>string</i></code> from <code><i>start</i></code> to <code><i>end</i></code> to an array of
+<a href="#octet">octets</a> corresponding to the <a href="#external-formats">external format</a> <code><i>external-format</i></code>. The defaults for
+<code><i>start</i></code> and <code><i>end</i></code>
+are <code>0</code> and <code>NIL</code> (meaning the length of the
+vector). The default for <code><i>external-format</i></code> is the
+value of
+evaluating <code>(<a
+href="#make-external-format">MAKE-EXTERNAL-FORMAT</a> :LATIN1)</code>
+
+</blockquote>
+
+<p><br>[Function]
+<br><a class=none name="octets-to-string"><b>octets-to-string</b> <i>vector <tt>&key</tt> external-format start end</i> => <i>string</i></a>
+
+<blockquote><br> Converts the Lisp vector <code><i>vector</i></code>
+of <a href="#octet">octets</a> from <code><i>start</i></code>
+to <code><i>end</i></code> to string using
+the <a href="#external-formats">external
+format</a> <code><i>external-format</i></code>. The defaults for
+<code><i>start</i></code> and <code><i>end</i></code>
+are <code>0</code> and the length of the vector. The default
+for <code><i>external-format</i></code> is the value of
+evaluating <code>(<a
+href="#make-external-format">MAKE-EXTERNAL-FORMAT</a> :LATIN1)</code>
+</blockquote>
+
+<br> <br><h3><a class=none name="position">File positions</a></h3>
+
+For <a href="#flexi-streams">flexi streams</a> as well
+as for <a href="#input-memory">in-memory
+streams</a>, <a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_file_p.htm">FILE-POSITION</a>
+will usually return <code>NIL</code> and do nothing when a second
+argument is supplied. This is correct
+w.r.t. the <a
+href="http://www.lispworks.com/documentation/HyperSpec/">ANSI
+standard</a>, but not very helpful. However, even
+with <a
+href="http://www.nhplace.com/kent/CL/Issues/stream-definition-by-user.html">Gray
+streams</a> there is no <em>portable</em> way to implement a better
+behaviour.
+<p>
+For <a href="http://www.lispworks.com/">LispWorks</a>
+and <a href="http://clisp.sf.net/">CLISP</a>,
+<a
+href="http://www.lispworks.com/documentation/HyperSpec/Body/f_file_p.htm">FILE-POSITION</a>
+for <a href="#flexi-streams">flexi streams</a> will work as if the
+function had been applied to the underlying stream, and
+for <a href="#input-memory">in-memory streams</a> it will try to do
+something sensible if the underlying data structure is a vector
+(i.e. <em>not</em> a list). Patches for other Common Lisp
+implementations should be sent to
+the <a
+href="http://common-lisp.net/project/cl-plus-ssl/#trivial-gray-streams">trivial-gray-streams</a>
+maintainers.
+
+<br> <br><h3><a class=none name="ack">Acknowledgements</a></h3>
+
+Thanks to David Lichteblau for numerous portability patches. Thanks
+to Igor Plekhov for the KOI8-R code. Thanks to Anton Vodonosov for
+numerous patches and additions.
+
+<p>
+$Header: /usr/local/cvsrep/flexi-streams/doc/index.html,v 1.96 2007/10/11 06:56:51 edi Exp $
+<p><a href="http://weitz.de/index.html">BACK TO MY HOMEPAGE</a>
+
+</body>
+</html>
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/external-format.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/external-format.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/external-format.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,147 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FLEXI-STREAMS; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/external-format.lisp,v 1.11 2007/01/01 23:46:49 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :flexi-streams)
+
+(defclass external-format ()
+ ((name :initarg :name
+ :reader external-format-name
+ :documentation "The name of the external format - a
+keyword.")
+ (id :initarg :id
+ :initform nil
+ :reader external-format-id
+ :documentation "If the external format denotes a Windows
+code page this ID specifies which one to use. Otherwise the
+value is ignored \(and usually NIL).")
+ (little-endian :initarg :little-endian
+ :initform *default-little-endian*
+ :reader external-format-little-endian
+ :documentation "Whether multi-octet values are
+read and written with the least significant octet first. For
+8-bit encodings like :ISO-8859-1 this value is ignored.")
+ (eol-style :initarg :eol-style
+ :reader external-format-eol-style
+ :documentation "The character\(s) to or from which
+a #\Newline will be translated - one of the keywords :CR, :LF,
+or :CRLF."))
+ (:documentation "EXTERNAL-FORMAT objects are used to denote
+encodings for flexi streams."))
+
+(defmethod make-load-form ((thing external-format) &optional environment)
+ "Defines a way to reconstruct external formats. Needed for OpenMCL."
+ (make-load-form-saving-slots thing :environment environment))
+
+(defun make-external-format% (name &key (little-endian *default-little-endian*)
+ id eol-style)
+ "Used internally by MAKE-EXTERNAL-FORMAT."
+ (let* ((real-name (normalize-external-format-name name))
+ (initargs
+ (cond ((or (iso-8859-name-p real-name)
+ (koi8-r-name-p real-name)
+ (ascii-name-p real-name))
+ (list :eol-style (or eol-style *default-eol-style*)))
+ ((code-page-name-p real-name)
+ (list :id (or (known-code-page-id-p id)
+ (error "Unknown code page ID ~S" id))
+ ;; default EOL style for Windows code pages is :CRLF
+ :eol-style (or eol-style :crlf)))
+ (t (list :eol-style (or eol-style *default-eol-style*)
+ :little-endian little-endian)))))
+ (apply #'make-instance 'external-format
+ :name real-name
+ initargs)))
+
+(defun make-external-format (name &rest args
+ &key (little-endian *default-little-endian*)
+ id eol-style)
+ "Creates and returns an external format object as specified.
+NAME is a keyword like :LATIN1 or :UTF-8, LITTLE-ENDIAN specifies
+the `endianess' of the external format and is ignored for 8-bit
+encodings, EOL-STYLE is one of the keywords :CR, :LF, or :CRLF
+which denote the end-of-line character \(sequence), ID is the ID
+of a Windows code page \(and ignored for other encodings)."
+ (declare (ignore id little-endian))
+ (let ((shortcut-args (cdr (assoc name +shortcut-map+))))
+ (cond (shortcut-args
+ (apply #'make-external-format%
+ (append shortcut-args
+ `(:eol-style ,eol-style))))
+ (t (apply #'make-external-format% name args)))))
+
+(defun external-format-equal (ef1 ef2)
+ "Checks whether two EXTERNAL-FORMAT objects denote the same
+encoding."
+ (let* ((name1 (external-format-name ef1))
+ (code-page-name-p (code-page-name-p name1)))
+ ;; they must habe the same canonical name
+ (and (eq name1
+ (external-format-name ef2))
+ ;; if both are code pages the IDs must be the same
+ (or (not code-page-name-p)
+ (eql (external-format-id ef1)
+ (external-format-id ef2)))
+ ;; for non-8-bit encodings the endianess must be the same
+ (or code-page-name-p
+ (ascii-name-p name1)
+ (koi8-r-name-p name1)
+ (iso-8859-name-p name1)
+ (eq name1 :utf-8)
+ (eq (not (external-format-little-endian ef1))
+ (not (external-format-little-endian ef2))))
+ ;; the EOL style must also be the same
+ (eq (external-format-eol-style ef1)
+ (external-format-eol-style ef2)))))
+
+(defun normalize-external-format (external-format)
+ "Returns a list which is a `normalized' representation of the
+external format EXTERNAL-FORMAT. Used internally by
+PRINT-OBJECT, for example. Basically, the result is argument
+list that can be fed back to MAKE-EXTERNAL-FORMAT to create an
+equivalent object."
+ (let ((name (external-format-name external-format))
+ (eol-style (external-format-eol-style external-format)))
+ (cond ((or (ascii-name-p name)
+ (koi8-r-name-p name)
+ (iso-8859-name-p name)
+ (eq name :utf-8))
+ (list name :eol-style eol-style))
+ ((code-page-name-p name)
+ (list name
+ :id (external-format-id external-format)
+ :eol-style eol-style))
+ (t (list name
+ :eol-style eol-style
+ :little-endian (external-format-little-endian external-format))))))
+
+(defmethod print-object ((object external-format) stream)
+ "How an EXTERNAL-FORMAT object is rendered. Uses
+NORMALIZE-EXTERNAL-FORMAT."
+ (print-unreadable-object (object stream :type t :identity t)
+ (prin1 (normalize-external-format object) stream)))
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/flexi-streams.asd
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/flexi-streams.asd 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/flexi-streams.asd 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,66 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/flexi-streams.asd,v 1.57 2007/10/11 06:56:49 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :cl-user)
+
+(defpackage :flexi-streams-system
+ (:use :asdf :cl))
+
+(in-package :flexi-streams-system)
+
+(defsystem :flexi-streams
+ :version "0.13.1"
+ :serial t
+ :components ((:file "packages")
+ (:file "ascii")
+ (:file "koi8-r")
+ (:file "iso-8859")
+ (:file "code-pages")
+ (:file "specials")
+ (:file "util")
+ (:file "external-format")
+ (:file "in-memory")
+ (:file "stream")
+ #+:lispworks (:file "lw-binary-stream")
+ (:file "output")
+ (:file "input")
+ (:file "strings"))
+ :depends-on (:trivial-gray-streams))
+
+(defsystem :flexi-streams-test
+ :components ((:module "test"
+ :serial t
+ :components ((:file "packages")
+ (:file "test"))))
+ :depends-on (:flexi-streams))
+
+(defmethod perform ((o test-op) (c (eql (find-system 'flexi-streams))))
+ (operate 'load-op 'flexi-streams-test)
+ (funcall (intern (symbol-name :run-tests)
+ (find-package :flexi-streams-test))))
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/in-memory.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/in-memory.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/in-memory.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,395 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FLEXI-STREAMS; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/in-memory.lisp,v 1.25 2007/01/12 00:08:15 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :flexi-streams)
+
+(defclass in-memory-stream (trivial-gray-stream-mixin)
+ ((transformer :initarg :transformer
+ :accessor in-memory-stream-transformer
+ :documentation "A function used to transform the
+written/read octet to the value stored/retrieved in/from the
+underlying vector.")
+ #+:cmu
+ (open-p :initform t
+ :accessor in-memory-stream-open-p
+ :documentation "For CMUCL we have to keep track of this
+manually."))
+ (:documentation "An IN-MEMORY-STREAM is a binary stream that reads
+octets from or writes octets to a sequence in RAM."))
+
+(defclass in-memory-input-stream (in-memory-stream fundamental-binary-input-stream)
+ ()
+ (:documentation "An IN-MEMORY-INPUT-STREAM is a binary stream that
+reads octets from a sequence in RAM."))
+
+#+:cmu
+(defmethod output-stream-p ((stream in-memory-input-stream))
+ "Explicitly states whether this is an output stream."
+ (declare (optimize speed))
+ nil)
+
+(defclass in-memory-output-stream (in-memory-stream fundamental-binary-output-stream)
+ ()
+ (:documentation "An IN-MEMORY-OUTPUT-STREAM is a binary stream that
+writes octets to a sequence in RAM."))
+
+#+:cmu
+(defmethod input-stream-p ((stream in-memory-output-stream))
+ "Explicitly states whether this is an input stream."
+ (declare (optimize speed))
+ nil)
+
+(defclass list-stream ()
+ ((list :initarg :list
+ :accessor list-stream-list
+ :documentation "The underlying list of the stream."))
+ (:documentation "A LIST-STREAM is a mixin for IN-MEMORY streams
+where the underlying sequence is a list."))
+
+(defclass vector-stream ()
+ ((vector :initarg :vector
+ :accessor vector-stream-vector
+ :documentation "The underlying vector of the stream which
+\(for output) must always be adjustable and have a fill pointer."))
+ (:documentation "A VECTOR-STREAM is a mixin for IN-MEMORY streams
+where the underlying sequence is a vector."))
+
+(defclass list-input-stream (list-stream in-memory-input-stream)
+ ()
+ (:documentation "A binary input stream that gets its data from an
+associated list of octets."))
+
+(defclass vector-input-stream (vector-stream in-memory-input-stream)
+ ((index :initarg :index
+ :accessor vector-stream-index
+ :type (integer 0 #.array-dimension-limit)
+ :documentation "An index into the underlying vector denoting
+the current position.")
+ (end :initarg :end
+ :accessor vector-stream-end
+ :type (integer 0 #.array-dimension-limit)
+ :documentation "An index into the underlying vector denoting
+the end of the available data."))
+ (:documentation "A binary input stream that gets its data from an
+associated vector of octets."))
+
+(defclass vector-output-stream (vector-stream in-memory-output-stream)
+ ()
+ (:documentation "A binary output stream that writes its data to an
+associated vector."))
+
+(define-condition in-memory-stream-error (stream-error)
+ ()
+ (:documentation "Superclass for all errors related to
+IN-MEMORY streams."))
+
+(define-condition in-memory-stream-closed-error (in-memory-stream-error)
+ ()
+ (:report (lambda (condition stream)
+ (format stream "~S is closed."
+ (stream-error-stream condition))))
+ (:documentation "An error that is signaled when someone is trying
+to read from or write to a closed IN-MEMORY stream."))
+
+#+:cmu
+(defmethod open-stream-p ((stream in-memory-stream))
+ "Returns a true value if STREAM is open. See ANSI standard."
+ (declare (optimize speed))
+ (in-memory-stream-open-p stream))
+
+#+:cmu
+(defmethod close ((stream in-memory-stream) &key abort)
+ "Closes the stream STREAM. See ANSI standard."
+ (declare (ignore abort)
+ (optimize speed))
+ (prog1
+ (in-memory-stream-open-p stream)
+ (setf (in-memory-stream-open-p stream) nil)))
+
+(defmethod check-if-open ((stream in-memory-stream))
+ "Checks if STREAM is open and signals an error otherwise."
+ (declare (optimize speed))
+ (unless (open-stream-p stream)
+ (error 'in-memory-stream-closed-error
+ :stream stream)))
+
+(defmethod stream-element-type ((stream in-memory-stream))
+ "The element type is always OCTET by definition."
+ (declare (optimize speed))
+ 'octet)
+
+(defmethod transform-octet ((stream in-memory-stream) octet)
+ "Applies the transformer of STREAM to octet and returns the result."
+ (funcall (or (in-memory-stream-transformer stream)
+ #'identity) octet))
+
+(defmethod stream-read-byte ((stream list-input-stream))
+ "Reads one byte by simply popping it off of the top of the list."
+ (declare (optimize speed))
+ (check-if-open stream)
+ (transform-octet stream (or (pop (list-stream-list stream))
+ (return-from stream-read-byte :eof))))
+
+(defmethod stream-listen ((stream list-input-stream))
+ "Checks whether list is not empty."
+ (declare (optimize speed))
+ (check-if-open stream)
+ (list-stream-list stream))
+
+(defmethod stream-read-sequence ((stream list-input-stream) sequence start end &key)
+ "Repeatedly pops elements from the list until it's empty."
+ (declare (optimize speed) (type (integer 0 *) start end))
+ (loop for index from start below end
+ while (list-stream-list stream)
+ do (setf (elt sequence index)
+ (pop (list-stream-list stream)))
+ finally (return index)))
+
+(defmethod stream-read-byte ((stream vector-input-stream))
+ "Reads one byte and increments INDEX pointer unless we're beyond
+END pointer."
+ (declare (optimize speed))
+ (check-if-open stream)
+ (let ((index (vector-stream-index stream)))
+ (cond ((< index (vector-stream-end stream))
+ (incf (vector-stream-index stream))
+ (transform-octet stream (aref (vector-stream-vector stream) index)))
+ (t :eof))))
+
+(defmethod stream-listen ((stream vector-input-stream))
+ "Checking whether INDEX is beyond END."
+ (declare (optimize speed))
+ (check-if-open stream)
+ (< (vector-stream-index stream) (vector-stream-end stream)))
+
+(defmethod stream-read-sequence ((stream vector-input-stream) sequence start end &key)
+ "Traverses both sequences in parallel until the end of one of them
+is reached."
+ (declare (optimize speed) (type (integer 0 *) start end))
+ (loop with vector-end of-type (integer 0 #.array-dimension-limit) = (vector-stream-end stream)
+ with vector = (vector-stream-vector stream)
+ for index from start below end
+ for vector-index of-type (integer 0 #.array-dimension-limit) = (vector-stream-index stream)
+ while (< vector-index vector-end)
+ do (setf (elt sequence index)
+ (aref vector vector-index))
+ (incf (vector-stream-index stream))
+ finally (return index)))
+
+(defmethod stream-write-byte ((stream vector-output-stream) byte)
+ "Writes a byte \(octet) by extending the underlying vector."
+ (declare (optimize speed))
+ (check-if-open stream)
+ (vector-push-extend (transform-octet stream byte)
+ (vector-stream-vector stream)))
+
+(defmethod stream-write-sequence ((stream vector-output-stream) sequence start end &key)
+ "Just calls VECTOR-PUSH-EXTEND repeatedly."
+ (declare (optimize speed) (type (integer 0 *) start end))
+ (loop with vector = (vector-stream-vector stream)
+ for index from start below end
+ do (vector-push-extend (elt sequence index) vector))
+ sequence)
+
+(defmethod stream-file-position ((stream vector-input-stream))
+ "Simply returns the index into the underlying vector."
+ (declare (optimize speed))
+ (vector-stream-index stream))
+
+(defmethod (setf stream-file-position) (position-spec (stream vector-input-stream))
+ "Sets the index into the underlying vector if POSITION-SPEC is acceptable."
+ (declare (optimize speed))
+ (setf (vector-stream-index stream)
+ (case position-spec
+ (:start 0)
+ (:end (vector-stream-end stream))
+ (otherwise
+ (unless (integerp position-spec)
+ (error 'flexi-stream-position-spec-error
+ :format-control "Unknown file position designator: ~S."
+ :format-arguments (list position-spec)
+ :position-spec position-spec))
+ (unless (<= 0 position-spec (vector-stream-end stream))
+ (error 'flexi-stream-position-spec-error
+ :format-control "File position designator ~S is out of bounds."
+ :format-arguments (list position-spec)
+ :position-spec position-spec))
+ position-spec)))
+ position-spec)
+
+(defmethod stream-file-position ((stream vector-output-stream))
+ "Simply returns the fill pointer of the underlying vector."
+ (declare (optimize speed))
+ (fill-pointer (vector-stream-vector stream)))
+
+(defmethod (setf stream-file-position) (position-spec (stream vector-output-stream))
+ "Sets the fill pointer underlying vector if POSITION-SPEC is
+acceptable. Adjusts the vector if necessary."
+ (declare (optimize speed))
+ (let* ((vector (vector-stream-vector stream))
+ (total-size (array-total-size vector))
+ (new-fill-pointer
+ (case position-spec
+ (:start 0)
+ (:end
+ (warn "File position designator :END doesn't really make sense for an output stream.")
+ total-size)
+ (otherwise
+ (unless (integerp position-spec)
+ (error 'flexi-stream-position-spec-error
+ :format-control "Unknown file position designator: ~S."
+ :format-arguments (list position-spec)
+ :position-spec position-spec))
+ (unless (<= 0 position-spec array-total-size-limit)
+ (error 'flexi-stream-position-spec-error
+ :format-control "File position designator ~S is out of bounds."
+ :format-arguments (list position-spec)
+ :position-spec position-spec))
+ position-spec))))
+ (when (> new-fill-pointer total-size)
+ (adjust-array vector new-fill-pointer))
+ (setf (fill-pointer vector) new-fill-pointer)
+ position-spec))
+
+(defmethod make-in-memory-input-stream ((vector vector) &key (start 0)
+ (end (length vector))
+ transformer)
+ "Returns a binary input stream which will supply, in order, the
+octets in the subsequence of VECTOR bounded by START and END.
+Each octet returned will be transformed in turn by the optional
+TRANSFORMER function."
+ (declare (optimize speed))
+ (make-instance 'vector-input-stream
+ :vector vector
+ :index start
+ :end end
+ :transformer transformer))
+
+(defmethod make-in-memory-input-stream ((list list) &key (start 0)
+ (end (length list))
+ transformer)
+ "Returns a binary input stream which will supply, in order, the
+octets in the subsequence of LIST bounded by START and END. Each
+octet returned will be transformed in turn by the optional
+TRANSFORMER function."
+ (declare (optimize speed))
+ (make-instance 'list-input-stream
+ :list (subseq list start end)
+ :transformer transformer))
+
+(defun make-output-vector (&key (element-type 'octet))
+ "Creates and returns an array which can be used as the underlying
+vector for a VECTOR-OUTPUT-STREAM."
+ (declare (optimize speed))
+ (make-array 0 :adjustable t
+ :fill-pointer 0
+ :element-type element-type))
+
+(defun make-in-memory-output-stream (&key (element-type 'octet) transformer)
+ "Returns a binary output stream which accepts objects of type
+ELEMENT-TYPE \(a subtype of OCTET) and makes available a sequence
+that contains the octes that were actually output. The octets
+stored will each be transformed by the optional TRANSFORMER
+function."
+ (declare (optimize speed))
+ (make-instance 'vector-output-stream
+ :vector (make-output-vector :element-type element-type)
+ :transformer transformer))
+
+(defmethod get-output-stream-sequence ((stream in-memory-output-stream) &key as-list)
+ "Returns a vector containing, in order, all the octets that have
+been output to the IN-MEMORY stream STREAM. This operation clears any
+octets on STREAM, so the vector contains only those octets which have
+been output since the last call to GET-OUTPUT-STREAM-SEQUENCE or since
+the creation of the stream, whichever occurred most recently. If
+AS-LIST is true the return value is coerced to a list."
+ (declare (optimize speed))
+ (prog1
+ (if as-list
+ (coerce (vector-stream-vector stream) 'list)
+ (vector-stream-vector stream))
+ (setf (vector-stream-vector stream)
+ (make-output-vector))))
+
+(defmethod output-stream-sequence-length ((stream in-memory-output-stream))
+ "Returns the current length of the underlying vector of the
+IN-MEMORY output stream STREAM."
+ (declare (optimize speed))
+ (length (the (simple-array * (*)) (vector-stream-vector stream))))
+
+(defmacro with-input-from-sequence ((var sequence &key start end transformer)
+ &body body)
+ "Creates an IN-MEMORY input stream from SEQUENCE using the
+parameters START and END, binds VAR to this stream and then
+executes the code in BODY. A function TRANSFORMER may optionally
+be specified to transform the returned octets. The stream is
+automatically closed on exit from WITH-INPUT-FROM-SEQUENCE, no
+matter whether the exit is normal or abnormal. The return value
+of this macro is the return value of BODY."
+ (with-rebinding (sequence)
+ `(let (,var)
+ (unwind-protect
+ (progn
+ (setq ,var (make-in-memory-input-stream ,sequence
+ :start (or ,start 0)
+ :end (or ,end (length ,sequence))
+ :transformer ,transformer))
+ ,@body)
+ (when ,var (close ,var))))))
+
+(defmacro with-output-to-sequence ((var &key as-list (element-type ''octet) transformer)
+ &body body)
+ "Creates an IN-MEMORY output stream, binds VAR to this stream
+and then executes the code in BODY. The stream stores data of
+type ELEMENT-TYPE \(a subtype of OCTET) which is \(optionally)
+transformed by the function TRANSFORMER prior to storage. The
+stream is automatically closed on exit from
+WITH-OUTPUT-TO-SEQUENCE, no matter whether the exit is normal or
+abnormal. The return value of this macro is a vector \(or a list
+if AS-LIST is true) containing the octets that were sent to the
+stream within BODY."
+ `(let (,var)
+ (unwind-protect
+ (progn
+ (setq ,var (make-in-memory-output-stream :element-type ,element-type
+ :transformer ,transformer))
+ ,@body
+ (get-output-stream-sequence ,var :as-list ,as-list))
+ (when ,var (close ,var)))))
+
+(declaim (inline translate-char))
+(defun translate-char (char-code external-format)
+ "Returns a list of octets which correspond to the
+representation of the character with character code CHAR-CODE
+when sent to a flexi stream with external format EXTERNAL-FORMAT.
+Used internally by UNREAD-CHAR%. See also STRING-TO-OCTETS."
+ (declare (optimize speed))
+ (with-output-to-sequence (list :as-list t)
+ (let ((stream (make-flexi-stream list :external-format external-format)))
+ (write-char (code-char char-code) stream))))
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/input.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/input.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/input.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,497 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FLEXI-STREAMS; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/input.lisp,v 1.48 2007/09/06 23:19:24 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :flexi-streams)
+
+#-:lispworks
+(defmethod read-byte* ((flexi-input-stream flexi-input-stream))
+ "Reads one byte \(octet) from the underlying stream of
+FLEXI-OUTPUT-STREAM \(or from the internal stack if it's not
+empty)."
+ (declare (optimize speed))
+ ;; we're using S instead of STREAM here because of an
+ ;; issue with SBCL:
+ ;; <http://article.gmane.org/gmane.lisp.steel-bank.general/1386>
+ (with-accessors ((position flexi-stream-position)
+ (bound flexi-stream-bound)
+ (octet-stack flexi-stream-octet-stack)
+ (s flexi-stream-stream))
+ flexi-input-stream
+ (declare (integer position)
+ (type (or null integer) bound))
+ (when (and bound
+ (>= position bound))
+ (return-from read-byte* nil))
+ (incf position)
+ (or (pop octet-stack)
+ (read-byte s nil nil)
+ (progn (decf position) nil))))
+
+#+:lispworks
+(defmethod read-byte* ((flexi-input-stream flexi-input-stream))
+ "Reads one byte \(octet) from the underlying stream of
+FLEXI-OUTPUT-STREAM \(or from the internal stack if it's not
+empty)."
+ (declare (optimize speed))
+ (with-accessors ((position flexi-stream-position)
+ (bound flexi-stream-bound)
+ (octet-stack flexi-stream-octet-stack)
+ (stream flexi-stream-stream))
+ flexi-input-stream
+ (declare (integer position)
+ (type (or null integer) bound))
+ (when (and bound
+ (>= position bound))
+ (return-from read-byte* nil))
+ (incf position)
+ (or (pop octet-stack)
+ ;; we use READ-SEQUENCE because READ-BYTE doesn't work with all
+ ;; bivalent streams in LispWorks
+ (let* ((buffer (make-array 1 :element-type 'octet))
+ (new-position (read-sequence buffer stream)))
+ (cond ((zerop new-position)
+ (decf position) nil)
+ (t (aref buffer 0)))))))
+
+#+:lispworks
+(defmethod read-byte* ((flexi-input-stream flexi-binary-input-stream))
+ "Reads one byte \(octet) from the underlying stream of
+FLEXI-OUTPUT-STREAM \(or from the internal stack if it's not empty).
+Optimized version \(only needed for LispWorks) in case the underlying
+stream is binary."
+ (declare (optimize speed))
+ (with-accessors ((position flexi-stream-position)
+ (bound flexi-stream-bound)
+ (octet-stack flexi-stream-octet-stack)
+ (stream flexi-stream-stream))
+ flexi-input-stream
+ (declare (integer position)
+ (type (or null integer) bound))
+ (when (and bound
+ (>= position bound))
+ (return-from read-byte* nil))
+ (incf position)
+ (or (pop octet-stack)
+ (read-byte stream nil nil)
+ (progn (decf position) nil))))
+
+(defmethod stream-clear-input ((flexi-input-stream flexi-input-stream))
+ "Calls the corresponding method for the underlying input stream
+and also clears the value of the OCTET-STACK slot."
+ (declare (optimize speed))
+ ;; note that we don't reset the POSITION slot
+ (with-accessors ((octet-stack flexi-stream-octet-stack)
+ (stream flexi-stream-stream))
+ flexi-input-stream
+ (setq octet-stack nil)
+ (clear-input stream)))
+
+(defmethod stream-listen ((flexi-input-stream flexi-input-stream))
+ "Calls the corresponding method for the underlying input stream
+but first checks if \(old) input is available in the OCTET-STACK
+slot."
+ (declare (optimize speed))
+ (with-accessors ((position flexi-stream-position)
+ (bound flexi-stream-bound)
+ (octet-stack flexi-stream-octet-stack)
+ (stream flexi-stream-stream))
+ flexi-input-stream
+ (when (and bound
+ (>= position bound))
+ (return-from stream-listen nil))
+ (or octet-stack (listen stream))))
+
+(defmethod stream-read-byte ((stream flexi-input-stream))
+ "Reads one byte \(octet) from the underlying stream."
+ (declare (optimize speed))
+ ;; set LAST-CHAR-CODE slot to NIL because we can't UNREAD-CHAR after
+ ;; this operation
+ (with-accessors ((last-char-code flexi-stream-last-char-code)
+ (last-octet flexi-stream-last-octet))
+ stream
+ (setq last-char-code nil)
+ (let ((octet (read-byte* stream)))
+ (setq last-octet octet)
+ (or octet :eof))))
+
+(defmethod unread-char% (char-code (flexi-input-stream flexi-input-stream))
+ "Used internally to put a character denoted by the character code
+CHAR-CODE which was already read back on the stream. Uses the
+OCTET-STACK slot and decrements the POSITION slot accordingly."
+ (declare (optimize speed) (inline translate-char))
+ (with-accessors ((position flexi-stream-position)
+ (octet-stack flexi-stream-octet-stack)
+ (external-format flexi-stream-external-format))
+ flexi-input-stream
+ (declare (integer position))
+ (let ((octets-read (translate-char char-code external-format)))
+ (decf position (length octets-read))
+ (setq octet-stack (append octets-read octet-stack)))))
+
+(defmacro define-char-reader ((stream-var stream-class) &body body)
+ "Helper macro to define methods for STREAM-READ-CHAR. Defines a
+method for the class STREAM-CLASS using the variable STREAM-VAR and
+the code body BODY wrapped with some standard code common to all
+methods defined here. The return value of BODY is a character code.
+In case of encoding problems, BODY must return the value returned by
+\(RECOVER-FROM-ENCODING-ERROR ...)."
+ (with-unique-names (char-code body-fn)
+ `(defmethod stream-read-char ((,stream-var ,stream-class))
+ "This method was generated with the DEFINE-CHAR-READER macro."
+ (declare (optimize speed))
+ ;; note that we do nothing for the :LF EOL style because we
+ ;; assume that #\Newline is the same as #\Linefeed in all
+ ;; Lisps which will use this library
+ (with-accessors ((last-octet flexi-stream-last-octet)
+ (last-char-code flexi-stream-last-char-code))
+ ,stream-var
+ ;; set LAST-OCTET slot to NIL because we can't UNREAD-BYTE after
+ ;; this operation
+ (setq last-octet nil)
+ (let ((,char-code
+ (flet ((,body-fn () ,@body))
+ (declare (inline ,body-fn) (dynamic-extent (function ,body-fn)))
+ (,body-fn))))
+ ;; remember this character and the current external format
+ ;; for UNREAD-CHAR
+ (setq last-char-code ,char-code)
+ (or (code-char ,char-code) ,char-code))))))
+
+(defun recover-from-encoding-error (flexi-stream format-control &rest format-args)
+ "Helper function used by the STREAM-READ-CHAR methods below to deal
+with encoding errors. Checks if *SUBSTITUTION-CHAR* is not NIL and
+returns its character code in this case. Otherwise signals a
+FLEXI-STREAM-ENCODING-ERROR as determined by the arguments to this
+function and provides a corresponding USE-VALUE restart."
+ (when *substitution-char*
+ (return-from recover-from-encoding-error (char-code *substitution-char*)))
+ (restart-case
+ (apply #'signal-encoding-error flexi-stream format-control format-args)
+ (use-value (char)
+ :report "Specify a character to be used instead."
+ :interactive (lambda ()
+ (loop
+ (format *query-io* "Type a character: ")
+ (let ((line (read-line *query-io*)))
+ (when (= 1 (length line))
+ (return (list (char line 0)))))))
+ (char-code char))))
+
+(define-char-reader (stream flexi-latin-1-input-stream)
+ (or (read-byte* stream)
+ (return-from stream-read-char :eof)))
+
+(define-char-reader (stream flexi-ascii-input-stream)
+ (let ((octet (or (read-byte* stream)
+ (return-from stream-read-char :eof))))
+ (declare (type octet octet))
+ (if (> octet 127)
+ (recover-from-encoding-error stream "No character which corresponds to octet #x~X." octet)
+ octet)))
+
+(define-char-reader (stream flexi-8-bit-input-stream)
+ (with-accessors ((encoding-table flexi-stream-encoding-table))
+ stream
+ (let* ((octet (or (read-byte* stream)
+ (return-from stream-read-char :eof)))
+ (char-code (aref (the (simple-array * *) encoding-table) octet)))
+ (declare (type octet octet))
+ (if (or (null char-code)
+ (= char-code 65533))
+ (recover-from-encoding-error stream "No character which corresponds to octet #x~X." octet)
+ char-code))))
+
+(define-char-reader (stream flexi-utf-8-input-stream)
+ (block body
+ (let (first-octet-seen)
+ (flet ((read-next-byte ()
+ (prog1
+ (or (read-byte* stream)
+ (cond (first-octet-seen
+ (return-from body
+ (recover-from-encoding-error stream
+ "End of file while in UTF-8 sequence.")))
+ (t (return-from stream-read-char :eof))))
+ (setq first-octet-seen t))))
+ (declare (inline read-next-byte) (dynamic-extent (function read-next-byte)))
+ (let ((octet (read-next-byte)))
+ (declare (type octet octet))
+ (multiple-value-bind (start count)
+ (cond ((zerop (logand octet #b10000000))
+ (values octet 0))
+ ((= #b11000000 (logand octet #b11100000))
+ (values (logand octet #b00011111) 1))
+ ((= #b11100000 (logand octet #b11110000))
+ (values (logand octet #b00001111) 2))
+ ((= #b11110000 (logand octet #b11111000))
+ (values (logand octet #b00000111) 3))
+ ((= #b11111000 (logand octet #b11111100))
+ (values (logand octet #b00000011) 4))
+ ((= #b11111100 (logand octet #b11111110))
+ (values (logand octet #b00000001) 5))
+ (t (return-from body
+ (recover-from-encoding-error stream
+ "Unexpected value #x~X at start of UTF-8 sequence."
+ octet))))
+ ;; note that we currently don't check for "overlong"
+ ;; sequences or other illegal values
+ (loop for result of-type (unsigned-byte 32)
+ = start then (+ (ash result 6)
+ (logand octet #b111111))
+ repeat count
+ for octet of-type octet = (read-next-byte)
+ unless (= #b10000000 (logand octet #b11000000))
+ do (return-from body
+ (recover-from-encoding-error stream
+ "Unexpected value #x~X in UTF-8 sequence." octet))
+ finally (return result))))))))
+
+(define-char-reader (stream flexi-utf-16-le-input-stream)
+ (block body
+ (let (first-octet-seen)
+ (labels ((read-next-byte ()
+ (prog1
+ (or (read-byte* stream)
+ (cond (first-octet-seen
+ (return-from body
+ (recover-from-encoding-error stream
+ "End of file while in UTF-16 sequence.")))
+ (t (return-from stream-read-char :eof))))
+ (setq first-octet-seen t)))
+ (read-next-word ()
+ (+ (the octet (read-next-byte))
+ (ash (the octet (read-next-byte)) 8))))
+ (declare (inline read-next-byte read-next-word)
+ (dynamic-extent (function read-next-byte) (function read-next-word)))
+ (let ((word (read-next-word)))
+ (cond ((<= #xd800 word #xdfff)
+ (let ((next-word (read-next-word)))
+ (unless (<= #xdc00 next-word #xdfff)
+ (return-from body
+ (recover-from-encoding-error stream "Unexpected UTF-16 word #x~X following #x~X."
+ next-word word)))
+ (+ (ash (logand #b1111111111 word) 10)
+ (logand #b1111111111 next-word)
+ #x10000)))
+ (t word)))))))
+
+(define-char-reader (stream flexi-utf-16-be-input-stream)
+ (block body
+ (let (first-octet-seen)
+ (labels ((read-next-byte ()
+ (prog1
+ (or (read-byte* stream)
+ (cond (first-octet-seen
+ (return-from body
+ (recover-from-encoding-error stream
+ "End of file while in UTF-16 sequence.")))
+ (t (return-from stream-read-char :eof))))
+ (setq first-octet-seen t)))
+ (read-next-word ()
+ (+ (ash (the octet (read-next-byte)) 8)
+ (the octet (read-next-byte)))))
+ (let ((word (read-next-word)))
+ (cond ((<= #xd800 word #xdfff)
+ (let ((next-word (read-next-word)))
+ (unless (<= #xdc00 next-word #xdfff)
+ (return-from body
+ (recover-from-encoding-error stream "Unexpected UTF-16 word #x~X following #x~X."
+ next-word word)))
+ (+ (ash (logand #b1111111111 word) 10)
+ (logand #b1111111111 next-word)
+ #x10000)))
+ (t word)))))))
+
+(define-char-reader (stream flexi-utf-32-le-input-stream)
+ (block body
+ (let (first-octet-seen)
+ (flet ((read-next-byte ()
+ (prog1
+ (or (read-byte* stream)
+ (cond (first-octet-seen
+ (return-from body
+ (recover-from-encoding-error stream
+ "End of file while in UTF-32 sequence.")))
+ (t (return-from stream-read-char :eof))))
+ (setq first-octet-seen t))))
+ (declare (inline read-next-byte) (dynamic-extent (function read-next-byte)))
+ (loop for count from 0 to 24 by 8
+ for octet of-type octet = (read-next-byte)
+ sum (ash octet count))))))
+
+(define-char-reader (stream flexi-utf-32-be-input-stream)
+ (block body
+ (let (first-octet-seen)
+ (flet ((read-next-byte ()
+ (prog1
+ (or (read-byte* stream)
+ (cond (first-octet-seen
+ (return-from body
+ (recover-from-encoding-error stream
+ "End of file while in UTF-32 sequence.")))
+ (t (return-from stream-read-char :eof))))
+ (setq first-octet-seen t))))
+ (declare (inline read-next-byte) (dynamic-extent (function read-next-byte)))
+ (loop for count from 24 downto 0 by 8
+ for octet of-type octet = (read-next-byte)
+ sum (ash octet count))))))
+
+(defmethod stream-read-char ((stream flexi-cr-mixin))
+ "The `base' method for all streams which need end-of-line
+conversion. Uses CALL-NEXT-METHOD to do the actual work of
+reading one or more characters from the stream."
+ (declare (optimize speed))
+ (let ((char (call-next-method)))
+ (when (eq char :eof)
+ (return-from stream-read-char :eof))
+ (with-accessors ((external-format flexi-stream-external-format)
+ (last-char-code flexi-stream-last-char-code))
+ stream
+ (when (eql char #\Return)
+ (case (external-format-eol-style external-format)
+ (:cr (setq char #\Newline
+ last-char-code #.(char-code #\Newline)))
+ ;; in the case :CRLF we have to look ahead one character
+ (:crlf (let ((next-char (call-next-method)))
+ (case next-char
+ (#\Linefeed
+ (setq char #\Newline
+ last-char-code #.(char-code #\Newline)))
+ (:eof)
+ ;; if the character we peeked at wasn't a
+ ;; linefeed character we push its
+ ;; constituents back onto our internal
+ ;; octet stack
+ (otherwise (unread-char% (char-code next-char) stream)))))))
+ char)))
+
+(defmethod stream-read-char-no-hang ((stream flexi-input-stream))
+ "Reads one character if the underlying stream has at least one
+octet available."
+ (declare (optimize speed))
+ ;; note that this may block for non-8-bit encodings - I think
+ ;; there's no easy way to handle this correctly
+ (and (stream-listen stream)
+ (stream-read-char stream)))
+
+(defmethod stream-read-sequence ((flexi-input-stream flexi-input-stream) sequence start end &key)
+ "Reads enough input from STREAM to fill SEQUENCE from START to END.
+If SEQUENCE is an array which can store octets we use READ-SEQUENCE to
+fill it in one fell swoop, otherwise we iterate using
+STREAM-READ-CHAR."
+ (declare (optimize speed)
+ (type (integer 0 *) start end))
+ (with-accessors ((last-char-code flexi-stream-last-char-code)
+ (last-octet flexi-stream-last-octet)
+ (stream flexi-stream-stream)
+ (position flexi-stream-position)
+ (octet-stack flexi-stream-octet-stack))
+ flexi-input-stream
+ (declare (integer position))
+ (cond ((and (arrayp sequence)
+ (subtypep 'octet (array-element-type sequence)))
+ (setf last-char-code nil)
+ (let ((cursor start))
+ (loop with stack = octet-stack
+ for continuep = (< cursor end)
+ for octet = (and continuep (pop stack))
+ while octet
+ do (setf (aref sequence cursor) (the octet octet))
+ (incf cursor))
+ (let ((index
+ (read-sequence sequence stream :start cursor :end end)))
+ (incf position (- index start))
+ (when (> index start)
+ (setq last-octet (aref sequence (1- index))))
+ index)))
+ (t
+ (loop for index from start below end
+ for element = (stream-read-char flexi-input-stream)
+ until (eq element :eof)
+ do (setf (elt sequence index) element)
+ finally (return index))))))
+
+(defmethod stream-unread-char ((stream flexi-input-stream) char)
+ "Implements UNREAD-CHAR for streams of type FLEXI-INPUT-STREAM.
+Makes sure CHAR will only be unread if it was the last character
+read and if it was read with the same encoding that's currently
+being used by the stream."
+ (declare (optimize speed))
+ (with-accessors ((last-char-code flexi-stream-last-char-code))
+ stream
+ (unless last-char-code
+ (error 'flexi-stream-simple-error
+ :format-control "No character to unread from this stream \(or external format has changed or last reading operation was binary)."))
+ (unless (= (char-code char) last-char-code)
+ (error 'flexi-stream-simple-error
+ :format-control "Last character read was different from ~S."
+ :format-arguments (list char)))
+ (unread-char% last-char-code stream)
+ (setq last-char-code nil)
+ nil))
+
+(defmethod unread-byte (byte (flexi-input-stream flexi-input-stream))
+ "Similar to UNREAD-CHAR in that it `unreads' the last octet from
+STREAM. Note that you can only call UNREAD-BYTE after a corresponding
+READ-BYTE."
+ (declare (optimize speed))
+ (with-accessors ((last-octet flexi-stream-last-octet)
+ (octet-stack flexi-stream-octet-stack)
+ (position flexi-stream-position))
+ flexi-input-stream
+ (unless last-octet
+ (error 'flexi-stream-simple-error
+ :format-control "No byte to unread from this stream \(or last reading operation read a character)."))
+ (unless (= byte last-octet)
+ (error 'flexi-stream-simple-error
+ :format-control "Last byte read was different from #x~X."
+ :format-arguments (list byte)))
+ (setq last-octet nil)
+ (decf (the integer position))
+ (push byte octet-stack)
+ nil))
+
+(defmethod peek-byte ((flexi-input-stream flexi-input-stream)
+ &optional peek-type (eof-error-p t) eof-value)
+ "PEEK-BYTE is like PEEK-CHAR, i.e. it returns an octet from
+FLEXI-INPUT-STREAM without actually removing it. If PEEK-TYPE is NIL
+the next octet is returned, if PEEK-TYPE is T, the next octet which is
+not 0 is returned, if PEEK-TYPE is an octet, the next octet which
+equals PEEK-TYPE is returned. EOF-ERROR-P and EOF-VALUE are
+interpreted as usual."
+ (declare (optimize speed))
+ (loop for octet = (read-byte flexi-input-stream eof-error-p eof-value)
+ until (cond ((null peek-type))
+ ((eql octet eof-value))
+ ((eq peek-type t)
+ (plusp octet))
+ (t (= octet peek-type)))
+ finally (unless (eql octet eof-value)
+ (unread-byte octet flexi-input-stream))
+ (return octet)))
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/iso-8859.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/iso-8859.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/iso-8859.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,53 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FLEXI-STREAMS; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/iso-8859.lisp,v 1.5 2007/01/01 23:46:49 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :flexi-streams)
+
+;;; the following code was auto-generated from files which can be
+;;; found at <ftp://ftp.unicode.org/Public/MAPPINGS/ISO8859/>
+
+(defvar +iso-8859-tables+
+ '((:iso-8859-1 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255))
+ (:iso-8859-2 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 260 728 321 164 317 346 167 168 352 350 356 377 173 381 379 176 261 731 322 180 318 347 711 184 353 351 357 378 733 382 380 340 193 194 258 196 313 262 199 268 201 280 203 282 205 206 270 272 323 327 211 212 336 214 215 344 366 218 368 220 221 354 223 341 225 226 259 228 314 263 231 269 233 281 235 283 237 238 271 273 324 328 243 244 337 246 247 345 367 250 369 252 253 355 729))
+ (:iso-8859-3 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 294 728 163 164 65533 292 167 168 304 350 286 308 173 65533 379 176 295 178 179 180 181 293 183 184 305 351 287 309 189 65533 380 192 193 194 65533 196 266 264 199 200 201 202 203 204 205 206 207 65533 209 210 211 212 288 214 215 284 217 218 219 220 364 348 223 224 225 226 65533 228 267 265 231 232 233 234 235 236 237 238 239 65533 241 242 243 244 289 246 247 285 249 250 251 252 365 349 729))
+ (:iso-8859-4 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 260 312 342 164 296 315 167 168 352 274 290 358 173 381 175 176 261 731 343 180 297 316 711 184 353 275 291 359 330 382 331 256 193 194 195 196 197 198 302 268 201 280 203 278 205 206 298 272 325 332 310 212 213 214 215 216 370 218 219 220 360 362 223 257 225 226 227 228 229 230 303 269 233 281 235 279 237 238 299 273 326 333 311 244 245 246 247 248 371 250 251 252 361 363 729))
+ (:iso-8859-5 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 173 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 8470 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 167 1118 1119))
+ (:iso-8859-6 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 65533 65533 65533 164 65533 65533 65533 65533 65533 65533 65533 1548 173 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 1563 65533 65533 65533 1567 65533 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 65533 65533 65533 65533 65533 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533))
+ (:iso-8859-7 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 8216 8217 163 8364 8367 166 167 168 169 890 171 172 173 65533 8213 176 177 178 179 900 901 902 183 904 905 906 187 908 189 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 65533 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 65533))
+ (:iso-8859-8 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 65533 162 163 164 165 166 167 168 169 215 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 247 187 188 189 190 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 65533 8215 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 65533 65533 8206 8207 65533))
+ (:iso-8859-9 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 286 209 210 211 212 213 214 215 216 217 218 219 220 304 350 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 287 241 242 243 244 245 246 247 248 249 250 251 252 305 351 255))
+ (:iso-8859-10 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 260 274 290 298 296 310 167 315 272 352 358 381 173 362 330 176 261 275 291 299 297 311 183 316 273 353 359 382 8213 363 331 256 193 194 195 196 197 198 302 268 201 280 203 278 205 206 207 208 325 332 211 212 213 214 360 216 370 218 219 220 221 222 223 257 225 226 227 228 229 230 303 269 233 281 235 279 237 238 239 240 326 333 243 244 245 246 361 248 371 250 251 252 253 254 312))
+ (:iso-8859-11 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 65533 65533 65533 65533 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 65533 65533 65533 65533))
+ (:iso-8859-13 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 8221 162 163 164 8222 166 167 216 169 342 171 172 173 174 198 176 177 178 179 8220 181 182 183 248 185 343 187 188 189 190 230 260 302 256 262 196 197 280 274 268 201 377 278 290 310 298 315 352 323 325 211 332 213 214 215 370 321 346 362 220 379 381 223 261 303 257 263 228 229 281 275 269 233 378 279 291 311 299 316 353 324 326 243 333 245 246 247 371 322 347 363 252 380 382 8217))
+ (:iso-8859-14 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 7682 7683 163 266 267 7690 167 7808 169 7810 7691 7922 173 174 376 7710 7711 288 289 7744 7745 182 7766 7809 7767 7811 7776 7923 7812 7813 7777 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 372 209 210 211 212 213 214 7786 216 217 218 219 220 221 374 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 373 241 242 243 244 245 246 7787 248 249 250 251 252 253 375 255))
+ (:iso-8859-15 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 8364 165 352 167 353 169 170 171 172 173 174 175 176 177 178 179 381 181 182 183 382 185 186 187 338 339 376 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255))
+ (:iso-8859-16 . #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 260 261 321 8364 8222 352 167 353 169 536 171 377 173 378 379 176 177 268 322 381 8221 182 183 382 269 537 187 338 339 376 380 192 193 194 258 196 262 198 199 200 201 202 203 204 205 206 207 272 323 210 211 212 336 214 346 368 217 218 219 220 280 538 223 224 225 226 259 228 263 230 231 232 233 234 235 236 237 238 239 273 324 242 243 244 337 246 347 369 249 250 251 252 281 539 255)))
+ "A list of the ISO-8859 encodings where each element is a cons
+with the car being a keyword denoting the encoding and the cdr
+being a vector enumerating the corresponding character codes.")
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/koi8-r.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/koi8-r.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/koi8-r.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,6 @@
+(in-package :flexi-streams)
+
+;; http://unicode.org/Public/MAPPINGS/VENDORS/MISC/KOI8-R.TXT
+(defvar +koi8-r-table+
+ #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 9472 9474 9484 9488 9492 9496 9500 9508 9516 9524 9532 9600 9604 9608 9612 9616 9617 9618 9619 8992 9632 8729 8730 8776 8804 8805 160 8993 176 178 183 247 9552 9553 9554 1105 9555 9556 9557 9558 9559 9560 9561 9562 9563 9564 9565 9566 9567 9568 9569 1025 9570 9571 9572 9573 9574 9575 9576 9577 9578 9579 9580 169 1102 1072 1073 1094 1076 1077 1092 1075 1093 1080 1081 1082 1083 1084 1085 1086 1087 1103 1088 1089 1090 1091 1078 1074 1100 1099 1079 1096 1101 1097 1095 1098 1070 1040 1041 1062 1044 1045 1060 1043 1061 1048 1049 1050 1051 1052 1053 1054 1055 1071 1056 1057 1058 1059 1046 1042 1068 1067 1047 1064 1069 1065 1063 1066)
+ "An array enumerating the character codes for the KOI8-R encoding.")
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/lw-binary-stream.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/lw-binary-stream.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/lw-binary-stream.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,441 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FLEXI-STREAMS; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/lw-binary-stream.lisp,v 1.10 2007/01/01 23:46:49 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :flexi-streams)
+
+(defclass flexi-binary-output-stream (flexi-output-stream)
+ ()
+ (:documentation "This class is for output streams where the
+underlying stream is binary. It exists solely for the purpose of
+optimizing output on LispWorks. See WRITE-BYTE*."))
+
+(defclass flexi-binary-input-stream (flexi-input-stream)
+ ()
+ (:documentation "This class is for input streams where the
+underlying stream is binary. It exists solely for the purpose of
+optimizing input on LispWorks. See READ-BYTE*."))
+
+(defclass flexi-binary-io-stream (flexi-binary-input-stream flexi-binary-output-stream flexi-io-stream)
+ ()
+ (:documentation "This class is for bidirectional streams where the
+underlying stream is binary. It exists solely for the purpose of
+optimizing input and output on LispWorks. See READ-BYTE* and
+WRITE-BYTE*."))
+
+(defclass flexi-binary-8-bit-input-stream (flexi-8-bit-input-stream flexi-binary-input-stream)
+ ()
+ (:documentation "Like FLEXI-8-BIT-INPUT-STREAM but optimized
+for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-8-bit-input-stream (flexi-cr-mixin flexi-binary-8-bit-input-stream)
+ ()
+ (:documentation "Like FLEXI-CR-8-BIT-INPUT-STREAM but optimized
+for LispWorks binary streams."))
+
+(defclass flexi-binary-ascii-input-stream (flexi-ascii-input-stream flexi-binary-8-bit-input-stream)
+ ()
+ (:documentation "Like FLEXI-ASCII-INPUT-STREAM but optimized
+for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-ascii-input-stream (flexi-cr-mixin flexi-binary-ascii-input-stream)
+ ()
+ (:documentation "Like FLEXI-CR-ASCII-INPUT-STREAM but optimized
+for LispWorks binary streams."))
+
+(defclass flexi-binary-latin-1-input-stream (flexi-latin-1-input-stream flexi-binary-8-bit-input-stream)
+ ()
+ (:documentation "Like FLEXI-LATIN-1-INPUT-STREAM but optimized
+for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-latin-1-input-stream (flexi-cr-mixin flexi-binary-latin-1-input-stream)
+ ()
+ (:documentation "Like FLEXI-CR-LATIN-1-INPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-32-le-input-stream (flexi-utf-32-le-input-stream flexi-binary-input-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-32-LE-INPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-32-le-input-stream (flexi-cr-mixin flexi-binary-utf-32-le-input-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-32-LE-INPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-32-be-input-stream (flexi-utf-32-be-input-stream flexi-binary-input-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-32-BE-INPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-32-be-input-stream (flexi-cr-mixin flexi-binary-utf-32-be-input-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-32-BE-INPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-16-le-input-stream (flexi-utf-16-le-input-stream flexi-binary-input-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-16-LE-INPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-16-le-input-stream (flexi-cr-mixin flexi-binary-utf-16-le-input-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-16-LE-INPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-16-be-input-stream (flexi-utf-16-be-input-stream flexi-binary-input-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-16-BE-INPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-16-be-input-stream (flexi-cr-mixin flexi-binary-utf-16-be-input-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-16-BE-INPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-8-input-stream (flexi-utf-8-input-stream flexi-binary-input-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-8-INPUT-STREAM but optimized
+for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-8-input-stream (flexi-cr-mixin flexi-binary-utf-8-input-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-8-INPUT-STREAM but optimized
+for LispWorks binary streams."))
+
+(defclass flexi-binary-8-bit-output-stream (flexi-8-bit-output-stream flexi-binary-output-stream)
+ ()
+ (:documentation "Like FLEXI-8-BIT-OUTPUT-STREAM but optimized
+for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-8-bit-output-stream (flexi-cr-mixin flexi-binary-8-bit-output-stream)
+ ()
+ (:documentation "Like FLEXI-CR-8-BIT-OUTPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-ascii-output-stream (flexi-ascii-output-stream flexi-binary-8-bit-output-stream)
+ ()
+ (:documentation "Like FLEXI-ASCII-OUTPUT-STREAM but optimized
+for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-ascii-output-stream (flexi-cr-mixin flexi-binary-ascii-output-stream)
+ ()
+ (:documentation "Like FLEXI-CR-ASCII-OUTPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-latin-1-output-stream (flexi-latin-1-output-stream flexi-binary-8-bit-output-stream)
+ ()
+ (:documentation "Like FLEXI-LATIN-1-OUTPUT-STREAM but optimized
+for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-latin-1-output-stream (flexi-cr-mixin flexi-binary-latin-1-output-stream)
+ ()
+ (:documentation "Like FLEXI-CR-LATIN-1-OUTPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-32-le-output-stream (flexi-utf-32-le-output-stream flexi-binary-output-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-32-LE-OUTPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-32-le-output-stream (flexi-cr-mixin flexi-binary-utf-32-le-output-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-32-LE-OUTPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-32-be-output-stream (flexi-utf-32-be-output-stream flexi-binary-output-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-32-BE-OUTPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-32-be-output-stream (flexi-cr-mixin flexi-binary-utf-32-be-output-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-32-BE-OUTPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-16-le-output-stream (flexi-utf-16-le-output-stream flexi-binary-output-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-16-LE-OUTPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-16-le-output-stream (flexi-cr-mixin flexi-binary-utf-16-le-output-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-16-LE-OUTPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-16-be-output-stream (flexi-utf-16-be-output-stream flexi-binary-output-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-16-BE-OUTPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-16-be-output-stream (flexi-cr-mixin flexi-binary-utf-16-be-output-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-16-BE-OUTPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-8-output-stream (flexi-utf-8-output-stream flexi-binary-output-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-8-OUTPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-8-output-stream (flexi-cr-mixin flexi-binary-utf-8-output-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-8-OUTPUT-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-8-bit-io-stream (flexi-binary-io-stream flexi-8-bit-io-stream)
+ ()
+ (:documentation "Like FLEXI-8-BIT-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-8-bit-io-stream (flexi-cr-mixin flexi-binary-8-bit-io-stream)
+ ()
+ (:documentation "Like FLEXI-CR-8-BIT-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-ascii-io-stream (flexi-ascii-io-stream flexi-binary-8-bit-io-stream)
+ ()
+ (:documentation "Like FLEXI-ASCII-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-ascii-io-stream (flexi-cr-mixin flexi-binary-ascii-io-stream)
+ ()
+ (:documentation "Like FLEXI-CR-ASCII-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-latin-1-io-stream (flexi-latin-1-io-stream flexi-binary-8-bit-io-stream)
+ ()
+ (:documentation "Like FLEXI-LATIN-1-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-latin-1-io-stream (flexi-cr-mixin flexi-binary-latin-1-io-stream)
+ ()
+ (:documentation "Like FLEXI-CR-LATIN-1-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-32-le-io-stream (flexi-utf-32-le-io-stream flexi-binary-io-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-32-LE-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-32-le-io-stream (flexi-cr-mixin flexi-binary-utf-32-le-io-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-32-LE-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-32-be-io-stream (flexi-utf-32-be-io-stream flexi-binary-io-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-32-BE-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-32-be-io-stream (flexi-cr-mixin flexi-binary-utf-32-be-io-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-32-BE-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-16-le-io-stream (flexi-utf-16-le-io-stream flexi-binary-io-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-16-LE-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-16-le-io-stream (flexi-cr-mixin flexi-binary-utf-16-le-io-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-16-LE-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-16-be-io-stream (flexi-utf-16-be-io-stream flexi-binary-io-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-16-BE-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-16-be-io-stream (flexi-cr-mixin flexi-binary-utf-16-be-io-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-16-BE-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-utf-8-io-stream (flexi-utf-8-io-stream flexi-binary-io-stream)
+ ()
+ (:documentation "Like FLEXI-UTF-8-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defclass flexi-binary-cr-utf-8-io-stream (flexi-cr-mixin flexi-binary-utf-8-io-stream)
+ ()
+ (:documentation "Like FLEXI-CR-UTF-8-IO-STREAM but
+optimized for LispWorks binary streams."))
+
+(defmethod set-class ((stream flexi-binary-input-stream))
+ "Changes the actual class of STREAM depending on its external format."
+ (declare (optimize speed))
+ (with-accessors ((external-format flexi-stream-external-format))
+ stream
+ (let ((external-format-name (external-format-name external-format))
+ (external-format-cr (not (eq (external-format-eol-style external-format) :lf))))
+ (change-class stream
+ (cond ((ascii-name-p external-format-name)
+ (if external-format-cr
+ 'flexi-binary-cr-ascii-input-stream
+ 'flexi-binary-ascii-input-stream))
+ ((eq external-format-name :iso-8859-1)
+ (if external-format-cr
+ 'flexi-binary-cr-latin-1-input-stream
+ 'flexi-binary-latin-1-input-stream))
+ ((or (koi8-r-name-p external-format-name)
+ (iso-8859-name-p external-format-name)
+ (code-page-name-p external-format-name))
+ (if external-format-cr
+ 'flexi-binary-cr-8-bit-input-stream
+ 'flexi-binary-8-bit-input-stream))
+ (t (case external-format-name
+ (:utf-8 (if external-format-cr
+ 'flexi-binary-cr-utf-8-input-stream
+ 'flexi-binary-utf-8-input-stream))
+ (:utf-16 (if external-format-cr
+ (if (external-format-little-endian external-format)
+ 'flexi-binary-cr-utf-16-le-input-stream
+ 'flexi-binary-cr-utf-16-be-input-stream)
+ (if (external-format-little-endian external-format)
+ 'flexi-binary-utf-16-le-input-stream
+ 'flexi-binary-utf-16-be-input-stream)))
+ (:utf-32 (if external-format-cr
+ (if (external-format-little-endian external-format)
+ 'flexi-binary-cr-utf-32-le-input-stream
+ 'flexi-binary-cr-utf-32-be-input-stream)
+ (if (external-format-little-endian external-format)
+ 'flexi-binary-utf-32-le-input-stream
+ 'flexi-binary-utf-32-be-input-stream))))))))))
+
+(defmethod set-class ((stream flexi-binary-output-stream))
+ "Changes the actual class of STREAM depending on its external format."
+ (declare (optimize speed))
+ (with-accessors ((external-format flexi-stream-external-format))
+ stream
+ (let ((external-format-name (external-format-name external-format))
+ (external-format-cr (not (eq (external-format-eol-style external-format) :lf))))
+ (change-class stream
+ (cond ((ascii-name-p external-format-name)
+ (if external-format-cr
+ 'flexi-binary-cr-ascii-output-stream
+ 'flexi-binary-ascii-output-stream))
+ ((eq external-format-name :iso-8859-1)
+ (if external-format-cr
+ 'flexi-binary-cr-latin-1-output-stream
+ 'flexi-binary-latin-1-output-stream))
+ ((or (koi8-r-name-p external-format-name)
+ (iso-8859-name-p external-format-name)
+ (code-page-name-p external-format-name))
+ (if external-format-cr
+ 'flexi-binary-cr-8-bit-output-stream
+ 'flexi-binary-8-bit-output-stream))
+ (t (case external-format-name
+ (:utf-8 (if external-format-cr
+ 'flexi-binary-cr-utf-8-output-stream
+ 'flexi-binary-utf-8-output-stream))
+ (:utf-16 (if external-format-cr
+ (if (external-format-little-endian external-format)
+ 'flexi-binary-cr-utf-16-le-output-stream
+ 'flexi-binary-cr-utf-16-be-output-stream)
+ (if (external-format-little-endian external-format)
+ 'flexi-binary-utf-16-le-output-stream
+ 'flexi-binary-utf-16-be-output-stream)))
+ (:utf-32 (if external-format-cr
+ (if (external-format-little-endian external-format)
+ 'flexi-binary-cr-utf-32-le-output-stream
+ 'flexi-binary-cr-utf-32-be-output-stream)
+ (if (external-format-little-endian external-format)
+ 'flexi-binary-utf-32-le-output-stream
+ 'flexi-binary-utf-32-be-output-stream))))))))))
+
+(defmethod set-class ((stream flexi-binary-io-stream))
+ "Changes the actual class of STREAM depending on its external format."
+ (declare (optimize speed))
+ (with-accessors ((external-format flexi-stream-external-format))
+ stream
+ (let ((external-format-name (external-format-name external-format))
+ (external-format-cr (not (eq (external-format-eol-style external-format) :lf))))
+ (change-class stream
+ (cond ((ascii-name-p external-format-name)
+ (if external-format-cr
+ 'flexi-binary-cr-ascii-io-stream
+ 'flexi-binary-ascii-io-stream))
+ ((eq external-format-name :iso-8859-1)
+ (if external-format-cr
+ 'flexi-binary-cr-latin-1-io-stream
+ 'flexi-binary-latin-1-io-stream))
+ ((or (koi8-r-name-p external-format-name)
+ (iso-8859-name-p external-format-name)
+ (code-page-name-p external-format-name))
+ (if external-format-cr
+ 'flexi-binary-cr-8-bit-io-stream
+ 'flexi-binary-8-bit-io-stream))
+ (t (case external-format-name
+ (:utf-8 (if external-format-cr
+ 'flexi-binary-cr-utf-8-io-stream
+ 'flexi-binary-utf-8-io-stream))
+ (:utf-16 (if external-format-cr
+ (if (external-format-little-endian external-format)
+ 'flexi-binary-cr-utf-16-le-io-stream
+ 'flexi-binary-cr-utf-16-be-io-stream)
+ (if (external-format-little-endian external-format)
+ 'flexi-binary-utf-16-le-io-stream
+ 'flexi-binary-utf-16-be-io-stream)))
+ (:utf-32 (if external-format-cr
+ (if (external-format-little-endian external-format)
+ 'flexi-binary-cr-utf-32-le-io-stream
+ 'flexi-binary-cr-utf-32-be-io-stream)
+ (if (external-format-little-endian external-format)
+ 'flexi-binary-utf-32-le-io-stream
+ 'flexi-binary-utf-32-be-io-stream))))))))))
+
+
+(defmethod initialize-instance :after ((flexi-stream flexi-output-stream) &rest initargs)
+ "Might change the class of FLEXI-STREAM for optimization purposes.
+Only needed for LispWorks."
+ (declare (ignore initargs)
+ (optimize speed))
+ (with-accessors ((stream flexi-stream-stream))
+ flexi-stream
+ (when (subtypep (stream-element-type stream) 'octet)
+ (change-class flexi-stream
+ (typecase flexi-stream
+ (flexi-io-stream 'flexi-binary-io-stream)
+ (otherwise 'flexi-binary-output-stream)))
+ (set-class flexi-stream))))
+
+(defmethod initialize-instance :after ((flexi-stream flexi-input-stream) &rest initargs)
+ "Might change the class of FLEXI-STREAM for optimization purposes.
+Only needed for LispWorks."
+ (declare (ignore initargs)
+ (optimize speed))
+ (with-accessors ((stream flexi-stream-stream))
+ flexi-stream
+ (when (subtypep (stream-element-type stream) 'octet)
+ (change-class flexi-stream
+ (typecase flexi-stream
+ (flexi-io-stream 'flexi-binary-io-stream)
+ (otherwise 'flexi-binary-input-stream)))
+ (set-class flexi-stream))))
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/output.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/output.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/output.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,310 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FLEXI-STREAMS; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/output.lisp,v 1.42 2007/09/13 19:35:49 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :flexi-streams)
+
+(defgeneric write-byte* (byte sink)
+ (:documentation "Writes one byte \(octet) to the underlying stream
+of SINK \(if SINK is a flexi stream) or adds the byte to the end of
+SINK \(if SINK is an array with a fill pointer)."))
+
+#-:lispworks
+(defmethod write-byte* (byte (sink flexi-output-stream))
+ (declare (optimize speed))
+ (with-accessors ((stream flexi-stream-stream))
+ sink
+ (write-byte byte stream)))
+
+#+:lispworks
+(defmethod write-byte* (byte (sink flexi-output-stream))
+ (declare (optimize speed))
+ ;; we use WRITE-SEQUENCE because WRITE-BYTE doesn't work with all
+ ;; bivalent streams in LispWorks (4.4.6)
+ (with-accessors ((stream flexi-stream-stream))
+ sink
+ (write-sequence (make-array 1 :element-type 'octet
+ :initial-element byte)
+ stream)
+ byte))
+
+#+:lispworks
+(defmethod write-byte* (byte (sink flexi-binary-output-stream))
+ "Optimized version \(only needed for LispWorks) in case the
+underlying stream is binary."
+ (declare (optimize speed))
+ (with-accessors ((stream flexi-stream-stream))
+ sink
+ (write-byte byte stream)))
+
+(defmethod write-byte* (byte (sink array))
+ (declare (optimize speed))
+ (vector-push byte sink))
+
+(defgeneric char-to-octets (stream char sink)
+ (:documentation "Converts the character CHAR to sequence of octets
+and sends this sequence to SINK. STREAM will always be a flexi stream
+which is used to determine how the character should be converted.
+This function does all the work for STREAM-WRITE-CHAR in which case
+SINK is the same as STREAM. It is also used in the implementation of
+STREAM-WRITE-SEQUENCE below."))
+
+(defmethod stream-write-char ((stream flexi-output-stream) char)
+ (declare (optimize speed))
+ (char-to-octets stream char stream))
+
+(defmethod char-to-octets ((stream flexi-latin-1-output-stream) char sink)
+ (declare (optimize speed))
+ (let ((octet (char-code char)))
+ (when (> octet 255)
+ (signal-encoding-error stream "~S is not a LATIN-1 character." char))
+ (write-byte* octet sink))
+ char)
+
+(defmethod char-to-octets ((stream flexi-ascii-output-stream) char sink)
+ (declare (optimize speed))
+ (let ((octet (char-code char)))
+ (when (> octet 127)
+ (signal-encoding-error stream "~S is not an ASCII character." char))
+ (write-byte* octet sink))
+ char)
+
+(defmethod char-to-octets ((stream flexi-8-bit-output-stream) char sink)
+ (declare (optimize speed))
+ (with-accessors ((encoding-hash flexi-stream-encoding-hash))
+ stream
+ (let ((octet (gethash (char-code char) encoding-hash)))
+ (unless octet
+ (signal-encoding-error stream "~S is not in this encoding." char))
+ (write-byte* octet sink))
+ char))
+
+(defmethod char-to-octets ((stream flexi-utf-8-output-stream) char sink)
+ (declare (optimize speed))
+ (let ((char-code (char-code char)))
+ (tagbody
+ (cond ((< char-code #x80)
+ (write-byte* char-code sink)
+ (go zero))
+ ((< char-code #x800)
+ (write-byte* (logior #b11000000 (ldb (byte 5 6) char-code)) sink)
+ (go one))
+ ((< char-code #x10000)
+ (write-byte* (logior #b11100000 (ldb (byte 4 12) char-code)) sink)
+ (go two))
+ ((< char-code #x200000)
+ (write-byte* (logior #b11110000 (ldb (byte 3 18) char-code)) sink)
+ (go three))
+ ((< char-code #x4000000)
+ (write-byte* (logior #b11111000 (ldb (byte 2 24) char-code)) sink)
+ (go four))
+ (t (write-byte* (logior #b11111100 (ldb (byte 1 30) char-code)) sink)))
+ (write-byte* (logior #b10000000 (ldb (byte 6 24) char-code)) sink)
+ four
+ (write-byte* (logior #b10000000 (ldb (byte 6 18) char-code)) sink)
+ three
+ (write-byte* (logior #b10000000 (ldb (byte 6 12) char-code)) sink)
+ two
+ (write-byte* (logior #b10000000 (ldb (byte 6 6) char-code)) sink)
+ one
+ (write-byte* (logior #b10000000 (ldb (byte 6 0) char-code)) sink)
+ zero))
+ char)
+
+(defmethod char-to-octets ((stream flexi-utf-16-le-output-stream) char sink)
+ (declare (optimize speed))
+ (flet ((write-word (word)
+ (write-byte* (ldb (byte 8 0) word) sink)
+ (write-byte* (ldb (byte 8 8) word) sink)))
+ (declare (inline write-word) (dynamic-extent (function write-word)))
+ (let ((char-code (char-code char)))
+ (cond ((< char-code #x10000)
+ (write-word char-code))
+ (t (decf char-code #x10000)
+ (write-word (logior #xd800 (ldb (byte 10 10) char-code)))
+ (write-word (logior #xdc00 (ldb (byte 10 0) char-code)))))))
+ char)
+
+(defmethod char-to-octets ((stream flexi-utf-16-be-output-stream) char sink)
+ (declare (optimize speed))
+ (flet ((write-word (word)
+ (write-byte* (ldb (byte 8 8) word) sink)
+ (write-byte* (ldb (byte 8 0) word) sink)))
+ (declare (inline write-word) (dynamic-extent (function write-word)))
+ (let ((char-code (char-code char)))
+ (cond ((< char-code #x10000)
+ (write-word char-code))
+ (t (decf char-code #x10000)
+ (write-word (logior #xd800 (ldb (byte 10 10) char-code)))
+ (write-word (logior #xdc00 (ldb (byte 10 0) char-code)))))))
+ char)
+
+(defmethod char-to-octets ((stream flexi-utf-32-le-output-stream) char sink)
+ (declare (optimize speed))
+ (loop with char-code = (char-code char)
+ for position in '(0 8 16 24) do
+ (write-byte* (ldb (byte 8 position) char-code) sink))
+ char)
+
+(defmethod char-to-octets ((stream flexi-utf-32-be-output-stream) char sink)
+ (declare (optimize speed))
+ (loop with char-code = (char-code char)
+ for position in '(24 16 8 0) do
+ (write-byte* (ldb (byte 8 position) char-code) sink))
+ char)
+
+(defmethod char-to-octets ((stream flexi-cr-mixin) char sink)
+ "The `base' method for all streams which need end-of-line
+conversion. Uses CALL-NEXT-METHOD to do the actual work of sending
+one or more characters to SINK."
+ (declare (optimize speed))
+ (with-accessors ((external-format flexi-stream-external-format))
+ stream
+ (case char
+ (#\Newline
+ (case (external-format-eol-style external-format)
+ (:cr (call-next-method stream #\Return sink))
+ (:crlf (call-next-method stream #\Return sink)
+ (call-next-method stream #\Linefeed sink))))
+ (otherwise (call-next-method)))
+ char))
+
+(defmethod stream-write-char :after ((stream flexi-output-stream) char)
+ (declare (optimize speed))
+ ;; update the column unless we're in the middle of the line and
+ ;; the current value is NIL
+ (with-accessors ((column flexi-stream-column))
+ stream
+ (cond ((char= char #\Newline) (setq column 0))
+ (column (incf (the integer column))))))
+
+(defmethod stream-clear-output ((flexi-output-stream flexi-output-stream))
+ "Simply calls the corresponding method for the underlying
+output stream."
+ (declare (optimize speed))
+ (with-accessors ((stream flexi-stream-stream))
+ flexi-output-stream
+ (clear-output stream)))
+
+(defmethod stream-finish-output ((flexi-output-stream flexi-output-stream))
+ "Simply calls the corresponding method for the underlying
+output stream."
+ (declare (optimize speed))
+ (with-accessors ((stream flexi-stream-stream))
+ flexi-output-stream
+ (finish-output stream)))
+
+(defmethod stream-force-output ((flexi-output-stream flexi-output-stream))
+ "Simply calls the corresponding method for the underlying
+output stream."
+ (declare (optimize speed))
+ (with-accessors ((stream flexi-stream-stream))
+ flexi-output-stream
+ (force-output stream)))
+
+(defmethod stream-line-column ((flexi-output-stream flexi-output-stream))
+ "Returns the column stored in the COLUMN slot of the
+FLEXI-OUTPUT-STREAM object STREAM."
+ (declare (optimize speed))
+ (with-accessors ((column flexi-stream-column))
+ flexi-output-stream
+ column))
+
+(defmethod stream-write-byte ((flexi-output-stream flexi-output-stream) byte)
+ "Writes a byte \(octet) to the underlying stream."
+ (declare (optimize speed))
+ (with-accessors ((column flexi-stream-column))
+ flexi-output-stream
+ ;; set column to NIL because we don't know how to handle binary
+ ;; output mixed with character output
+ (setq column nil)
+ (write-byte* byte flexi-output-stream)))
+
+#+:allegro
+(defmethod stream-terpri ((stream flexi-output-stream))
+ "Writes a #\Newline character to the underlying stream."
+ (declare (optimize speed))
+ ;; needed for AllegroCL - grrr...
+ (stream-write-char stream #\Newline))
+
+(defmethod stream-write-sequence ((flexi-output-stream flexi-output-stream) sequence start end &key)
+ "Writes all elements of the sequence SEQUENCE from START to END
+to the underlying stream. The elements can be either octets or
+characters. Characters are output according to the current
+encoding \(external format) of the FLEXI-OUTPUT-STREAM object
+STREAM."
+ (declare (optimize speed)
+ (type (integer 0 *) start end))
+ (with-accessors ((stream flexi-stream-stream)
+ (column flexi-stream-column))
+ flexi-output-stream
+ (cond ((and (arrayp sequence)
+ (subtypep (array-element-type sequence) 'octet))
+ ;; set column to NIL because we don't know how to handle binary
+ ;; output mixed with character output
+ (setq column nil)
+ (write-sequence sequence stream :start start :end end))
+ (t (loop for index from start below end
+ for element = (elt sequence index)
+ when (characterp element) do
+ (stream-write-char flexi-output-stream element)
+ else do
+ (stream-write-byte flexi-output-stream element))
+ sequence))))
+
+(defmethod stream-write-sequence ((stream flexi-output-stream) (sequence string) start end &key)
+ "Optimized method for the cases where SEQUENCE is a string. Fills
+an internal buffer and uses repeated calls to WRITE-SEQUENCE to write
+to the underlying stream."
+ (declare (optimize speed)
+ (type (integer 0 *) start end))
+ (let* ((buffer (make-array (+ +buffer-size+ 20)
+ :element-type '(unsigned-byte 8)
+ :fill-pointer 0))
+ (last-newline-pos (position #\Newline sequence
+ :test #'char=
+ :start start
+ :end end
+ :from-end t)))
+ (loop for index from start below end
+ do (char-to-octets stream (aref sequence index) buffer)
+ when (>= (fill-pointer buffer) +buffer-size+) do
+ (write-sequence buffer (flexi-stream-stream stream))
+ (setf (fill-pointer buffer) 0)
+ finally (when (>= (fill-pointer buffer) 0)
+ (write-sequence buffer (flexi-stream-stream stream))))
+ (setf (flexi-stream-column stream)
+ (cond (last-newline-pos (- end last-newline-pos 1))
+ ((flexi-stream-column stream)
+ (+ (flexi-stream-column stream) (- end start))))))
+ sequence)
+
+(defmethod stream-write-string ((stream flexi-output-stream) string
+ &optional (start 0) (end (length string)))
+ "Simply hands over to the optimized method for STREAM-WRITE-SEQUENCE."
+ (stream-write-sequence stream string start (or end (length string))))
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/packages.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/packages.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/packages.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,86 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/packages.lisp,v 1.29 2007/10/11 06:56:49 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :cl-user)
+
+(unless (find-symbol (if (eq (readtable-case *readtable*) :upcase)
+ "STREAM-FILE-POSITION"
+ "stream-file-position")
+ :trivial-gray-streams)
+ (error "You need a newer version of TRIVIAL-GRAY-STREAMS."))
+
+(defpackage :flexi-streams
+ (:use :cl :trivial-gray-streams)
+ (:nicknames :flex)
+ #+:lispworks
+ (:shadow :with-accessors)
+ (:export :*default-eol-style*
+ :*default-little-endian*
+ :*substitution-char*
+ :external-format-eol-style
+ :external-format-equal
+ :external-format-id
+ :external-format-little-endian
+ :external-format-name
+ :flexi-input-stream
+ :flexi-output-stream
+ :flexi-io-stream
+ :flexi-stream
+ :flexi-stream-bound
+ :flexi-stream-external-format
+ :flexi-stream-encoding-error
+ :flexi-stream-element-type
+ :flexi-stream-element-type-error
+ :flexi-stream-element-type-error-element-type
+ :flexi-stream-error
+ :flexi-stream-column
+ :flexi-stream-position
+ :flexi-stream-position-spec-error
+ :flexi-stream-position-spec-error-position-spec
+ :flexi-stream-stream
+ :get-output-stream-sequence
+ :in-memory-stream
+ :in-memory-stream-closed-error
+ :in-memory-stream-error
+ :in-memory-input-stream
+ :in-memory-output-stream
+ :list-stream
+ :make-external-format
+ :make-in-memory-input-stream
+ :make-in-memory-output-stream
+ :make-flexi-stream
+ :octet
+ :octets-to-string
+ :output-stream-sequence-length
+ :peek-byte
+ :string-to-octets
+ :unread-byte
+ :vector-stream
+ :with-input-from-sequence
+ :with-output-to-sequence))
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/specials.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/specials.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/specials.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,184 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FLEXI-STREAMS; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/specials.lisp,v 1.24 2007/09/05 11:30:23 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :flexi-streams)
+
+(deftype octet ()
+ "A shortcut for \(UNSIGNED-BYTE 8)."
+ '(unsigned-byte 8))
+
+(defvar +name-map+
+ '((:utf8 . :utf-8)
+ (:utf16 . :utf-16)
+ (:ucs2 . :utf-16)
+ (:ucs-2 . :utf-16)
+ (:unicode . :utf-16)
+ (:utf32 . :utf-32)
+ (:ucs4 . :utf-32)
+ (:ucs-4 . :utf-32)
+ (:ascii . :us-ascii)
+ (:koi8r . :koi8-r)
+ (:latin-1 . :iso-8859-1)
+ (:latin1 . :iso-8859-1)
+ (:latin-2 . :iso-8859-2)
+ (:latin2 . :iso-8859-2)
+ (:latin-3 . :iso-8859-3)
+ (:latin3 . :iso-8859-3)
+ (:latin-4 . :iso-8859-4)
+ (:latin4 . :iso-8859-4)
+ (:cyrillic . :iso-8859-5)
+ (:arabic . :iso-8859-6)
+ (:greek . :iso-8859-7)
+ (:hebrew . :iso-8859-8)
+ (:latin-5 . :iso-8859-9)
+ (:latin5 . :iso-8859-9)
+ (:latin-6 . :iso-8859-10)
+ (:latin6 . :iso-8859-10)
+ (:thai . :iso-8859-11)
+ (:latin-7 . :iso-8859-13)
+ (:latin7 . :iso-8859-13)
+ (:latin-8 . :iso-8859-14)
+ (:latin8 . :iso-8859-14)
+ (:latin-9 . :iso-8859-15)
+ (:latin9 . :iso-8859-15)
+ (:latin-0 . :iso-8859-15)
+ (:latin0 . :iso-8859-15)
+ (:latin-10 . :iso-8859-16)
+ (:latin10 . :iso-8859-16)
+ (:codepage . :code-page)
+ #+(and :lispworks :win32)
+ (win32:code-page . :code-page))
+ "An alist which mapes alternative names for external formats to
+their canonical counterparts.")
+
+(defvar +shortcut-map+
+ '((:ucs-2le . (:ucs-2 :little-endian t))
+ (:ucs-2be . (:ucs-2 :little-endian nil))
+ (:ucs-4le . (:ucs-4 :little-endian t))
+ (:ucs-4be . (:ucs-4 :little-endian nil))
+ (:utf-16le . (:utf-16 :little-endian t))
+ (:utf-16be . (:utf-16 :little-endian nil))
+ (:utf-32le . (:utf-32 :little-endian t))
+ (:utf-32be . (:utf-32 :little-endian nil))
+ (:ibm437 . (:code-page :id 437))
+ (:ibm850 . (:code-page :id 850))
+ (:ibm852 . (:code-page :id 852))
+ (:ibm855 . (:code-page :id 855))
+ (:ibm857 . (:code-page :id 857))
+ (:ibm860 . (:code-page :id 860))
+ (:ibm861 . (:code-page :id 861))
+ (:ibm862 . (:code-page :id 862))
+ (:ibm863 . (:code-page :id 863))
+ (:ibm864 . (:code-page :id 864))
+ (:ibm865 . (:code-page :id 865))
+ (:ibm866 . (:code-page :id 866))
+ (:ibm869 . (:code-page :id 869))
+ (:windows-1250 . (:code-page :id 1250))
+ (:windows-1251 . (:code-page :id 1251))
+ (:windows-1252 . (:code-page :id 1252))
+ (:windows-1253 . (:code-page :id 1253))
+ (:windows-1254 . (:code-page :id 1254))
+ (:windows-1255 . (:code-page :id 1255))
+ (:windows-1256 . (:code-page :id 1256))
+ (:windows-1257 . (:code-page :id 1257))
+ (:windows-1258 . (:code-page :id 1258)))
+ "An alist which maps shortcuts for external formats to their
+long forms.")
+
+(defvar *default-eol-style*
+ #+:win32 :crlf
+ #-:win32 :lf
+ "The end-of-line style used by external formats if none is
+explicitly given. Depends on the OS the code is compiled on.")
+
+(defvar *default-little-endian*
+ #+:little-endian t
+ #-:little-endian nil
+ "Whether external formats are little-endian by default
+\(i.e. unless explicitly specified). Depends on the platform
+the code is compiled on.")
+
+(defvar *substitution-char* nil
+ "If this value is not NIL, it should be a character which is used
+\(as if by a USE-VALUE restart) whenever during reading an error of
+type FLEXI-STREAM-ENCODING-ERROR would have been signaled otherwise.")
+
+(defun invert-table (table)
+ "`Inverts' an array which maps octets to character codes to a
+hash tables which maps character codes to octets."
+ (let ((hash (make-hash-table)))
+ (loop for octet from 0
+ for char-code across table
+ unless (= char-code 65533)
+ do (setf (gethash char-code hash) octet))
+ hash))
+
+(defvar +iso-8859-hashes+
+ (loop for (name . table) in +iso-8859-tables+
+ collect (cons name (invert-table table)))
+ "An alist which maps names for ISO-8859 encodings to hash
+tables which map character codes to the corresponding octets.")
+
+(defvar +code-page-hashes+
+ (loop for (id . table) in +code-page-tables+
+ collect (cons id (invert-table table)))
+ "An alist which maps IDs of Windows code pages to hash tables
+which map character codes to the corresponding octets.")
+
+(defvar +ascii-hash+ (invert-table +ascii-table+)
+ "A hash table which maps US-ASCII character codes to the
+corresponding octets.")
+
+(defvar +koi8-r-hash+ (invert-table +koi8-r-table+)
+ "A hash table which maps KOI8-R character codes to the
+corresponding octets.")
+
+(defconstant +buffer-size+ 8192
+ "Size of buffers used for internal purposes.")
+
+(pushnew :flexi-streams *features*)
+
+;; stuff for Nikodemus Siivola's HYPERDOC
+;; see <http://common-lisp.net/project/hyperdoc/>
+;; and <http://www.cliki.net/hyperdoc>
+;; also used by LW-ADD-ONS
+
+(defvar *hyperdoc-base-uri* "http://weitz.de/flexi-streams/")
+
+(let ((exported-symbols-alist
+ (loop for symbol being the external-symbols of :flexi-streams
+ collect (cons symbol
+ (concatenate 'string
+ "#"
+ (string-downcase symbol))))))
+ (defun hyperdoc-lookup (symbol type)
+ (declare (ignore type))
+ (cdr (assoc symbol
+ exported-symbols-alist
+ :test #'eq))))
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/stream.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/stream.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/stream.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,730 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FLEXI-STREAMS; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/stream.lisp,v 1.50 2007/09/06 23:46:29 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :flexi-streams)
+
+(defclass flexi-stream (trivial-gray-stream-mixin)
+ ((stream :initarg :stream
+ :reader flexi-stream-stream
+ :documentation "The actual stream that's used for
+input and/or output. It must be capable of reading/writing
+octets with READ-SEQUENCE and/or WRITE-SEQUENCE.")
+ (external-format :initform (make-external-format :iso-8859-1)
+ :initarg :flexi-stream-external-format
+ :accessor flexi-stream-external-format
+ :documentation "The encoding currently used
+by this stream. Can be changed on the fly.")
+ (element-type :initform #+:lispworks 'lw:simple-char #-:lispworks 'character
+ :initarg :element-type
+ :accessor flexi-stream-element-type
+ :documentation "The element type of this stream."))
+ (:documentation "A FLEXI-STREAM object is a stream that's
+`layered' atop an existing binary/bivalent stream in order to
+allow for multi-octet external formats. FLEXI-STREAM itself is a
+mixin and should not be instantiated."))
+
+(define-condition flexi-stream-error (stream-error)
+ ()
+ (:documentation "Superclass for all errors related to
+flexi streams."))
+
+(define-condition flexi-stream-simple-error (flexi-stream-error simple-condition)
+ ()
+ (:documentation "Like FLEXI-STREAM-ERROR but with formatting
+capabilities."))
+
+(define-condition flexi-stream-element-type-error (flexi-stream-error)
+ ((element-type :initarg :element-type
+ :reader flexi-stream-element-type-error-element-type))
+ (:report (lambda (condition stream)
+ (format stream "Element type ~S not allowed."
+ (flexi-stream-element-type-error-element-type condition))))
+ (:documentation "Errors of this type are signaled if the flexi
+stream has a wrong element type."))
+
+(define-condition flexi-stream-encoding-error (flexi-stream-simple-error)
+ ()
+ (:documentation "Errors of this type are signaled if there is an
+encoding problem."))
+
+(define-condition flexi-stream-position-spec-error (flexi-stream-simple-error)
+ ((position-spec :initarg :position-spec
+ :reader flexi-stream-position-spec-error-position-spec))
+ (:documentation "Errors of this type are signaled if an
+erroneous position spec is used in conjunction with
+FILE-POSITION."))
+
+(defun signal-encoding-error (flexi-stream format-control &rest format-args)
+ "Convenience function similar to ERROR to signal conditions of type
+FLEXI-STREAM-ENCODING-ERROR."
+ (error 'flexi-stream-encoding-error
+ :format-control format-control
+ :format-arguments format-args
+ :stream flexi-stream))
+
+(defun maybe-convert-external-format (external-format)
+ "Given an external format designator \(a keyword, a list, or an
+EXTERNAL-FORMAT object) returns the corresponding EXTERNAL-FORMAT
+object."
+ (typecase external-format
+ (symbol (make-external-format external-format))
+ (list (apply #'make-external-format external-format))
+ (otherwise external-format)))
+
+(defmethod initialize-instance :after ((flexi-stream flexi-stream) &rest initargs)
+ "Makes sure the EXTERNAL-FORMAT and ELEMENT-TYPE slots contain
+reasonable values."
+ (declare (ignore initargs)
+ (optimize speed))
+ (with-accessors ((external-format flexi-stream-external-format)
+ (element-type flexi-stream-element-type))
+ flexi-stream
+ (unless (or (subtypep element-type 'character)
+ (subtypep element-type 'octet))
+ (error 'flexi-stream-element-type-error
+ :element-type element-type
+ :stream flexi-stream))
+ (setq external-format (maybe-convert-external-format external-format)))
+ ;; set actual class and maybe contents of 8-bit encoding slots
+ (set-class flexi-stream))
+
+(defmethod (setf flexi-stream-external-format) :around (new-value (flexi-stream flexi-stream))
+ "Converts the new value to an EXTERNAL-FORMAT object if
+necessary."
+ (call-next-method (maybe-convert-external-format new-value) flexi-stream))
+
+(defmethod (setf flexi-stream-element-type) :before (new-value (flexi-stream flexi-stream))
+ "Checks whether the new value makes sense before it is set."
+ (unless (or (subtypep new-value 'character)
+ (subtypep new-value 'octet))
+ (error 'flexi-stream-element-type-error
+ :element-type new-value
+ :stream flexi-stream)))
+
+(defmethod stream-element-type ((stream flexi-stream))
+ "Returns the element type that was provided by the creator of
+the stream."
+ (declare (optimize speed))
+ (flexi-stream-element-type stream))
+
+(defmethod close ((stream flexi-stream) &key abort)
+ "Closes the flexi stream by closing the underlying `real'
+stream."
+ (declare (optimize speed))
+ (with-accessors ((stream flexi-stream-stream))
+ stream
+ (cond ((open-stream-p stream)
+ (close stream :abort abort))
+ (t nil))))
+
+(defmethod open-stream-p ((stream flexi-stream))
+ "A flexi stream is open if its underlying stream is open."
+ (declare (optimize speed))
+ (open-stream-p (flexi-stream-stream stream)))
+
+(defmethod stream-file-position ((stream flexi-stream))
+ "Dispatch to method for underlying stream."
+ (declare (optimize speed))
+ (stream-file-position (flexi-stream-stream stream)))
+
+(defmethod (setf stream-file-position) (position-spec (stream flexi-stream))
+ "Dispatch to method for underlying stream."
+ (declare (optimize speed))
+ (setf (stream-file-position (flexi-stream-stream stream))
+ position-spec))
+
+(defclass flexi-output-stream (flexi-stream fundamental-binary-output-stream
+ fundamental-character-output-stream)
+ ((column :initform 0
+ :accessor flexi-stream-column
+ :documentation "The current output column. A
+non-negative integer or NIL."))
+ (:documentation "A FLEXI-OUTPUT-STREAM is a FLEXI-STREAM that
+can actually be instatiated and used for output. Don't use
+MAKE-INSTANCE to create a new FLEXI-OUTPUT-STREAM but use
+MAKE-FLEXI-STREAM instead."))
+
+#+:cmu
+(defmethod input-stream-p ((stream flexi-output-stream))
+ "Explicitly states whether this is an input stream."
+ (declare (optimize speed))
+ nil)
+
+(defclass flexi-input-stream (flexi-stream fundamental-binary-input-stream
+ fundamental-character-input-stream)
+ ((last-char-code :initform nil
+ :accessor flexi-stream-last-char-code
+ :documentation "This slot either holds NIL or the
+last character \(code) read successfully. This is mainly used for
+UNREAD-CHAR sanity checks.")
+ (last-octet :initform nil
+ :accessor flexi-stream-last-octet
+ :documentation "This slot either holds NIL or the last
+octet read successfully from the stream using a `binary' operation
+such as READ-BYTE. This is mainly used for UNREAD-BYTE sanity
+checks.")
+ (octet-stack :initform nil
+ :accessor flexi-stream-octet-stack
+ :documentation "A small buffer which holds octets
+that were already read from the underlying stream but not yet
+used to produce characters. This is mainly used if we have to
+look ahead for a CR/LF line ending.")
+ (position :initform 0
+ :initarg :position
+ :type integer
+ :accessor flexi-stream-position
+ :documentation "The position within the stream where each
+octet read counts as one.")
+ (bound :initform nil
+ :initarg :bound
+ :type (or null integer)
+ :accessor flexi-stream-bound
+ :documentation "When this is not NIL, it must be an integer
+and the stream will behave as if no more data is available as soon as
+POSITION is greater or equal than this value."))
+ (:documentation "A FLEXI-INPUT-STREAM is a FLEXI-STREAM that
+can actually be instatiated and used for input. Don't use
+MAKE-INSTANCE to create a new FLEXI-INPUT-STREAM but use
+MAKE-FLEXI-STREAM instead."))
+
+#+:cmu
+(defmethod output-stream-p ((stream flexi-input-stream))
+ "Explicitly states whether this is an output stream."
+ (declare (optimize speed))
+ nil)
+
+(defclass flexi-io-stream (flexi-input-stream flexi-output-stream)
+ ()
+ (:documentation "A FLEXI-IO-STREAM is a FLEXI-STREAM that can
+actually be instatiated and used for input and output. Don't use
+MAKE-INSTANCE to create a new FLEXI-IO-STREAM but use
+MAKE-FLEXI-STREAM instead."))
+
+(defclass flexi-cr-mixin ()
+ ()
+ (:documentation "A mixin for flexi streams which need
+end-of-line conversion, i.e. for those where the end-of-line
+designator is /not/ the single character #\Linefeed."))
+
+(defclass flexi-8-bit-input-stream (flexi-input-stream)
+ ((encoding-table :accessor flexi-stream-encoding-table))
+ (:documentation "The class for all flexi input streams which
+use an 8-bit encoding and thus need an additional slot for the
+encoding table."))
+
+(defclass flexi-cr-8-bit-input-stream (flexi-cr-mixin flexi-8-bit-input-stream)
+ ()
+ (:documentation "The class for all flexi input streams which
+use an 8-bit encoding /and/ need end-of-line conversion."))
+
+(defclass flexi-ascii-input-stream (flexi-8-bit-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the US-ASCCI encoding."))
+
+(defclass flexi-cr-ascii-input-stream (flexi-cr-mixin flexi-ascii-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the US-ASCCI encoding /and/ need end-of-line conversion."))
+
+(defclass flexi-latin-1-input-stream (flexi-8-bit-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the ISO-8859-1 encoding."))
+
+(defclass flexi-cr-latin-1-input-stream (flexi-cr-mixin flexi-latin-1-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the ISO-8859-1 encoding /and/ need end-of-line conversion."))
+
+(defclass flexi-utf-32-le-input-stream (flexi-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the UTF-32 encoding with little-endian byte ordering."))
+
+(defclass flexi-cr-utf-32-le-input-stream (flexi-cr-mixin flexi-utf-32-le-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the UTF-32 encoding with little-endian byte ordering /and/
+need end-of-line conversion."))
+
+(defclass flexi-utf-32-be-input-stream (flexi-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the UTF-32 encoding with big-endian byte ordering."))
+
+(defclass flexi-cr-utf-32-be-input-stream (flexi-cr-mixin flexi-utf-32-be-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the UTF-32 encoding with big-endian byte ordering /and/ need
+end-of-line conversion."))
+
+(defclass flexi-utf-16-le-input-stream (flexi-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the UTF-16 encoding with little-endian byte ordering."))
+
+(defclass flexi-cr-utf-16-le-input-stream (flexi-cr-mixin flexi-utf-16-le-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the UTF-16 encoding with little-endian byte ordering /and/
+need end-of-line conversion."))
+
+(defclass flexi-utf-16-be-input-stream (flexi-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the UTF-16 encoding with big-endian byte ordering."))
+
+(defclass flexi-cr-utf-16-be-input-stream (flexi-cr-mixin flexi-utf-16-be-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the UTF-16 encoding with big-endian byte ordering /and/ need
+end-of-line conversion."))
+
+(defclass flexi-utf-8-input-stream (flexi-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the UTF-8 encoding."))
+
+(defclass flexi-cr-utf-8-input-stream (flexi-cr-mixin flexi-utf-8-input-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the UTF-8 encoding /and/ need end-of-line conversion."))
+
+(defclass flexi-8-bit-output-stream (flexi-output-stream)
+ ((encoding-hash :accessor flexi-stream-encoding-hash))
+ (:documentation "The class for all flexi output streams which
+use an 8-bit encoding and thus need an additional slot for the
+encoding table."))
+
+(defclass flexi-cr-8-bit-output-stream (flexi-cr-mixin flexi-8-bit-output-stream)
+ ()
+ (:documentation "The class for all flexi output streams which
+use an 8-bit encoding /and/ need end-of-line conversion."))
+
+(defclass flexi-ascii-output-stream (flexi-8-bit-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the US-ASCCI encoding."))
+
+(defclass flexi-cr-ascii-output-stream (flexi-cr-mixin flexi-ascii-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the US-ASCCI encoding /and/ need end-of-line conversion."))
+
+(defclass flexi-latin-1-output-stream (flexi-8-bit-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the ISO-8859-1 encoding."))
+
+(defclass flexi-cr-latin-1-output-stream (flexi-cr-mixin flexi-latin-1-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the ISO-8859-1 encoding /and/ need end-of-line conversion."))
+
+(defclass flexi-utf-32-le-output-stream (flexi-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the UTF-32 encoding with little-endian byte ordering."))
+
+(defclass flexi-cr-utf-32-le-output-stream (flexi-cr-mixin flexi-utf-32-le-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the UTF-32 encoding with little-endian byte ordering /and/
+need end-of-line conversion."))
+
+(defclass flexi-utf-32-be-output-stream (flexi-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the UTF-32 encoding with big-endian byte ordering."))
+
+(defclass flexi-cr-utf-32-be-output-stream (flexi-cr-mixin flexi-utf-32-be-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the UTF-32 encoding with big-endian byte ordering /and/ need
+end-of-line conversion."))
+
+(defclass flexi-utf-16-le-output-stream (flexi-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the UTF-16 encoding with little-endian byte ordering."))
+
+(defclass flexi-cr-utf-16-le-output-stream (flexi-cr-mixin flexi-utf-16-le-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the UTF-16 encoding with little-endian byte ordering /and/
+need end-of-line conversion."))
+
+(defclass flexi-utf-16-be-output-stream (flexi-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the UTF-16 encoding with big-endian byte ordering."))
+
+(defclass flexi-cr-utf-16-be-output-stream (flexi-cr-mixin flexi-utf-16-be-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the UTF-16 encoding with big-endian byte ordering /and/ need
+end-of-line conversion."))
+
+(defclass flexi-utf-8-output-stream (flexi-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the UTF-8 encoding."))
+
+(defclass flexi-cr-utf-8-output-stream (flexi-cr-mixin flexi-utf-8-output-stream)
+ ()
+ (:documentation "Special class for flexi output streams which
+use the UTF-8 encoding /and/ need end-of-line conversion."))
+
+(defclass flexi-8-bit-io-stream (flexi-8-bit-input-stream flexi-8-bit-output-stream flexi-io-stream)
+ ()
+ (:documentation "The class for all flexi I/O streams which use
+an 8-bit encoding and thus need an additional slot for the
+encoding table."))
+
+(defclass flexi-cr-8-bit-io-stream (flexi-cr-mixin flexi-8-bit-io-stream)
+ ()
+ (:documentation "The class for all flexi I/O streams which use
+an 8-bit encoding /and/ need end-of-line conversion."))
+
+(defclass flexi-ascii-io-stream (flexi-ascii-input-stream flexi-ascii-output-stream flexi-io-stream)
+ ()
+ (:documentation "Special class for flexi I/O streams which use
+the US-ASCCI encoding."))
+
+(defclass flexi-cr-ascii-io-stream (flexi-cr-mixin flexi-ascii-io-stream)
+ ()
+ (:documentation "Special class for flexi I/O streams which use
+the US-ASCCI encoding /and/ need end-of-line conversion."))
+
+(defclass flexi-latin-1-io-stream (flexi-latin-1-input-stream flexi-latin-1-output-stream flexi-io-stream)
+ ()
+ (:documentation "Special class for flexi I/O streams which use
+the ISO-8859-1 encoding."))
+
+(defclass flexi-cr-latin-1-io-stream (flexi-cr-mixin flexi-latin-1-io-stream)
+ ()
+ (:documentation "Special class for flexi input streams which
+use the ISO-8859-1 encoding /and/ need end-of-line conversion."))
+
+(defclass flexi-utf-32-le-io-stream (flexi-utf-32-le-input-stream
+ flexi-utf-32-le-output-stream
+ flexi-io-stream)
+ ()
+ (:documentation "Special class for flexi I/O streams which use
+the UTF-32 encoding with little-endian byte ordering."))
+
+(defclass flexi-cr-utf-32-le-io-stream (flexi-cr-mixin flexi-utf-32-le-io-stream)
+ ()
+ (:documentation "Special class for flexi I/O streams which use
+the UTF-32 encoding with little-endian byte ordering /and/ need
+end-of-line conversion."))
+
+(defclass flexi-utf-32-be-io-stream (flexi-utf-32-be-input-stream
+ flexi-utf-32-be-output-stream
+ flexi-io-stream)
+ ()
+ (:documentation "Special class for flexi I/O streams which use
+the UTF-32 encoding with big-endian byte ordering."))
+
+(defclass flexi-cr-utf-32-be-io-stream (flexi-cr-mixin flexi-utf-32-be-io-stream)
+ ()
+ (:documentation "Special class for flexi I/O streams which use
+the UTF-32 encoding with big-endian byte ordering /and/ need
+end-of-line conversion."))
+
+(defclass flexi-utf-16-le-io-stream (flexi-utf-16-le-input-stream
+ flexi-utf-16-le-output-stream
+ flexi-io-stream)
+ ()
+ (:documentation "Special class for flexi I/O streams which use
+the UTF-16 encoding with little-endian byte ordering."))
+
+(defclass flexi-cr-utf-16-le-io-stream (flexi-cr-mixin flexi-utf-16-le-io-stream)
+ ()
+ (:documentation "Special class for flexi I/O streams which use
+the UTF-16 encoding with little-endian byte ordering /and/ need
+end-of-line conversion."))
+
+(defclass flexi-utf-16-be-io-stream (flexi-utf-16-be-input-stream
+ flexi-utf-16-be-output-stream
+ flexi-io-stream)
+ ()
+ (:documentation "Special class for flexi I/O streams which use
+the UTF-16 encoding with big-endian byte ordering."))
+
+(defclass flexi-cr-utf-16-be-io-stream (flexi-cr-mixin flexi-utf-16-be-io-stream)
+ ()
+ (:documentation "Special class for flexi I/O streams which use
+the UTF-16 encoding with big-endian byte ordering /and/ need
+end-of-line conversion."))
+
+(defclass flexi-utf-8-io-stream (flexi-utf-8-input-stream flexi-utf-8-output-stream flexi-io-stream)
+ ()
+ (:documentation "Special class for flexi I/O streams which use
+the UTF-8 encoding."))
+
+(defclass flexi-cr-utf-8-io-stream (flexi-cr-mixin flexi-utf-8-io-stream)
+ ()
+ (:documentation "Special class for flexi I/O streams which use
+the UTF-8 encoding /and/ need end-of-line conversion."))
+
+(defmethod (setf flexi-stream-external-format) :after (new-value (stream flexi-stream))
+ "After we've changed the external format of a flexi stream, we
+might have to change its actual class and maybe also the contents
+of its 8-bit encoding slots."
+ (declare (ignore new-value)
+ (optimize speed))
+ ;; note that it's potentially dangerous to call SET-CLASS from
+ ;; within a method, see for example this thread:
+ ;; <http://thread.gmane.org/gmane.lisp.lispworks.general/6269>
+ (set-class stream))
+
+(defmethod set-class ((stream flexi-input-stream))
+ "Changes the actual class of STREAM depending on its external format."
+ (declare (optimize speed))
+ (with-accessors ((external-format flexi-stream-external-format))
+ stream
+ (let ((external-format-name (external-format-name external-format))
+ (external-format-cr (not (eq (external-format-eol-style external-format) :lf))))
+ (change-class stream
+ (cond ((ascii-name-p external-format-name)
+ (if external-format-cr
+ 'flexi-cr-ascii-input-stream
+ 'flexi-ascii-input-stream))
+ ((eq external-format-name :iso-8859-1)
+ (if external-format-cr
+ 'flexi-cr-latin-1-input-stream
+ 'flexi-latin-1-input-stream))
+ ((or (koi8-r-name-p external-format-name)
+ (iso-8859-name-p external-format-name)
+ (code-page-name-p external-format-name))
+ (if external-format-cr
+ 'flexi-cr-8-bit-input-stream
+ 'flexi-8-bit-input-stream))
+ (t (case external-format-name
+ (:utf-8 (if external-format-cr
+ 'flexi-cr-utf-8-input-stream
+ 'flexi-utf-8-input-stream))
+ (:utf-16 (if external-format-cr
+ (if (external-format-little-endian external-format)
+ 'flexi-cr-utf-16-le-input-stream
+ 'flexi-cr-utf-16-be-input-stream)
+ (if (external-format-little-endian external-format)
+ 'flexi-utf-16-le-input-stream
+ 'flexi-utf-16-be-input-stream)))
+ (:utf-32 (if external-format-cr
+ (if (external-format-little-endian external-format)
+ 'flexi-cr-utf-32-le-input-stream
+ 'flexi-cr-utf-32-be-input-stream)
+ (if (external-format-little-endian external-format)
+ 'flexi-utf-32-le-input-stream
+ 'flexi-utf-32-be-input-stream))))))))))
+
+(defmethod set-class ((stream flexi-output-stream))
+ "Changes the actual class of STREAM depending on its external format."
+ (declare (optimize speed))
+ (with-accessors ((external-format flexi-stream-external-format))
+ stream
+ (let ((external-format-name (external-format-name external-format))
+ (external-format-cr (not (eq (external-format-eol-style external-format) :lf))))
+ (change-class stream
+ (cond ((ascii-name-p external-format-name)
+ (if external-format-cr
+ 'flexi-cr-ascii-output-stream
+ 'flexi-ascii-output-stream))
+ ((eq external-format-name :iso-8859-1)
+ (if external-format-cr
+ 'flexi-cr-latin-1-output-stream
+ 'flexi-latin-1-output-stream))
+ ((or (koi8-r-name-p external-format-name)
+ (iso-8859-name-p external-format-name)
+ (code-page-name-p external-format-name))
+ (if external-format-cr
+ 'flexi-cr-8-bit-output-stream
+ 'flexi-8-bit-output-stream))
+ (t (case external-format-name
+ (:utf-8 (if external-format-cr
+ 'flexi-cr-utf-8-output-stream
+ 'flexi-utf-8-output-stream))
+ (:utf-16 (if external-format-cr
+ (if (external-format-little-endian external-format)
+ 'flexi-cr-utf-16-le-output-stream
+ 'flexi-cr-utf-16-be-output-stream)
+ (if (external-format-little-endian external-format)
+ 'flexi-utf-16-le-output-stream
+ 'flexi-utf-16-be-output-stream)))
+ (:utf-32 (if external-format-cr
+ (if (external-format-little-endian external-format)
+ 'flexi-cr-utf-32-le-output-stream
+ 'flexi-cr-utf-32-be-output-stream)
+ (if (external-format-little-endian external-format)
+ 'flexi-utf-32-le-output-stream
+ 'flexi-utf-32-be-output-stream))))))))))
+
+(defmethod set-class ((stream flexi-io-stream))
+ "Changes the actual class of STREAM depending on its external format."
+ (declare (optimize speed))
+ (with-accessors ((external-format flexi-stream-external-format))
+ stream
+ (let ((external-format-name (external-format-name external-format))
+ (external-format-cr (not (eq (external-format-eol-style external-format) :lf))))
+ (change-class stream
+ (cond ((ascii-name-p external-format-name)
+ (if external-format-cr
+ 'flexi-cr-ascii-io-stream
+ 'flexi-ascii-io-stream))
+ ((eq external-format-name :iso-8859-1)
+ (if external-format-cr
+ 'flexi-cr-latin-1-io-stream
+ 'flexi-latin-1-io-stream))
+ ((or (koi8-r-name-p external-format-name)
+ (iso-8859-name-p external-format-name)
+ (code-page-name-p external-format-name))
+ (if external-format-cr
+ 'flexi-cr-8-bit-io-stream
+ 'flexi-8-bit-io-stream))
+ (t (case external-format-name
+ (:utf-8 (if external-format-cr
+ 'flexi-cr-utf-8-io-stream
+ 'flexi-utf-8-io-stream))
+ (:utf-16 (if external-format-cr
+ (if (external-format-little-endian external-format)
+ 'flexi-cr-utf-16-le-io-stream
+ 'flexi-cr-utf-16-be-io-stream)
+ (if (external-format-little-endian external-format)
+ 'flexi-utf-16-le-io-stream
+ 'flexi-utf-16-be-io-stream)))
+ (:utf-32 (if external-format-cr
+ (if (external-format-little-endian external-format)
+ 'flexi-cr-utf-32-le-io-stream
+ 'flexi-cr-utf-32-be-io-stream)
+ (if (external-format-little-endian external-format)
+ 'flexi-utf-32-le-io-stream
+ 'flexi-utf-32-be-io-stream))))))))))
+
+(defmethod set-class :after ((stream flexi-stream))
+ "After we've changed the actual class of a flexi stream we may
+have to set the contents of the 8-bit enconding slots as well."
+ (declare (optimize speed))
+ (set-encoding-table stream)
+ (set-encoding-hash stream))
+
+(defgeneric set-encoding-table (stream)
+ (:method (stream))
+ (:documentation "Sets the value of the ENCODING-TABLE slot of
+STREAM if necessary. The default method does nothing."))
+
+(defgeneric set-encoding-hash (stream)
+ (:method (stream))
+ (:documentation "Sets the value of the ENCODING-HASH slot of
+STREAM if necessary. The default method does nothing."))
+
+(defmethod set-encoding-table ((stream flexi-8-bit-input-stream))
+ "Sets the value of the ENCODING-TABLE slot of STREAM depending
+on its external format."
+ (declare (optimize speed))
+ (with-accessors ((external-format flexi-stream-external-format)
+ (encoding-table flexi-stream-encoding-table))
+ stream
+ (let ((external-format-name (external-format-name external-format)))
+ (setq encoding-table
+ (cond ((ascii-name-p external-format-name) +ascii-table+)
+ ((koi8-r-name-p external-format-name) +koi8-r-table+)
+ ((iso-8859-name-p external-format-name)
+ (cdr (assoc external-format-name +iso-8859-tables+ :test #'eq)))
+ ((code-page-name-p external-format-name)
+ (cdr (assoc (external-format-id external-format) +code-page-tables+))))))))
+
+(defmethod set-encoding-hash ((stream flexi-8-bit-output-stream))
+ "Sets the value of the ENCODING-HASH slot of STREAM depending
+on its external format."
+ (declare (optimize speed))
+ (with-accessors ((external-format flexi-stream-external-format)
+ (encoding-hash flexi-stream-encoding-hash))
+ stream
+ (let ((external-format-name (external-format-name external-format)))
+ (setq encoding-hash
+ (cond ((ascii-name-p external-format-name) +ascii-hash+)
+ ((koi8-r-name-p external-format-name) +koi8-r-hash+)
+ ((iso-8859-name-p external-format-name)
+ (cdr (assoc external-format-name +iso-8859-hashes+ :test #'eq)))
+ ((code-page-name-p external-format-name)
+ (cdr (assoc (external-format-id external-format) +code-page-hashes+))))))))
+
+
+#+:cmu
+(defmethod input-stream-p ((stream flexi-io-stream))
+ "Explicitly states whether this is an input stream."
+ (declare (optimize speed))
+ t)
+
+#+:cmu
+(defmethod output-stream-p ((stream flexi-io-stream))
+ "Explicitly states whether this is an output stream."
+ (declare (optimize speed))
+ t)
+
+(defun make-flexi-stream (stream &rest args
+ &key (external-format (make-external-format :iso-8859-1))
+ element-type column position bound)
+ "Creates and returns a new flexi stream. STREAM must be an open
+binary or `bivalent' stream, i.e. it must be capable of
+reading/writing octets with READ-SEQUENCE and/or WRITE-SEQUENCE. The
+resulting flexi stream is an input stream if and only if STREAM is an
+input stream. Likewise, it's an output stream if and only if STREAM
+is an output stream. The default for ELEMENT-TYPE is LW:SIMPLE-CHAR
+on LispWorks and CHARACTER on other Lisps. EXTERNAL-FORMAT must be an
+EXTERNAL-FORMAT object or a symbol or a list denoting such an object.
+COLUMN is the initial column of the stream which is either a
+non-negative integer or NIL. The COLUMN argument must only be used
+for output streams. POSITION \(only used for input streams) should be
+an integer and it denotes the position the stream is in - it will be
+increased by one for each octet read. BOUND \(only used for input
+streams) should be NIL or an integer. If BOUND is not NIL and
+POSITION has gone beyond BOUND, then the stream will behave as if no
+more input is available."
+ ;; these arguments are ignored - they are only there to provide a
+ ;; meaningful parameter list for IDEs
+ (declare (ignore element-type column position bound))
+ (unless (and (streamp stream)
+ (open-stream-p stream))
+ (error "~S should have been an open stream." stream))
+ (apply #'make-instance
+ ;; actual type depends on STREAM
+ (cond ((and (input-stream-p stream)
+ (output-stream-p stream))
+ 'flexi-io-stream)
+ ((input-stream-p stream)
+ 'flexi-input-stream)
+ ((output-stream-p stream)
+ 'flexi-output-stream))
+ :stream stream
+ :flexi-stream-external-format external-format
+ (sans args :external-format)))
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/strings.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/strings.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/strings.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,56 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FLEXI-STREAMS; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/strings.lisp,v 1.4 2007/01/01 23:46:49 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :flexi-streams)
+
+(defun string-to-octets (string &key (external-format (make-external-format :latin1))
+ (start 0) end)
+ "Converts the Lisp string STRING from START to END to an array of
+octets corresponding to the external format EXTERNAL-FORMAT."
+ (declare (optimize speed))
+ (with-output-to-sequence (out)
+ (let ((flexi (make-flexi-stream out :external-format external-format)))
+ (write-string string flexi :start start :end end))))
+
+(defun octets-to-string (vector &key (external-format (make-external-format :latin1))
+ (start 0) (end (length vector)))
+ "Converts the Lisp vector VECTOR of octets from START to END to
+string using the external format EXTERNAL-FORMAT."
+ (declare (optimize speed))
+ (with-input-from-sequence (in vector :start start :end end)
+ (let ((flexi (make-flexi-stream in :external-format external-format))
+ (result (make-array (- end start)
+ :element-type #+:lispworks 'lw:simple-char
+ #-:lispworks 'character
+ :fill-pointer t)))
+ (setf (fill-pointer result)
+ (read-sequence result flexi))
+ result)))
+
+
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/README
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/README 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/README 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,4 @@
+The reference files in this directory were created/converted using a
+mixture of GNU recode and the native internationalization facilities
+of LispWorks and AllegroCL, i.e. we're not testing FLEXI-STREAMS
+against files created by itself (which would be kind of useless).
\ No newline at end of file
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/README
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_latin8_cr.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_latin8_cr.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_latin8_cr.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1 @@
+:���� ��� ����� �� ����� ��� ������ � 1
���� ���-�� ���� ���� ��� ���� ����� � 2
:���� ���-�� ����� ����� ����
:���-���� ��� ��� ����� ����� � 3
����� ����� ���-�� ����-�� ����� ���� � 4
:���� ���� ���� ���
���� ��� ����� ��� ���� ����� ����� � 5
:��� ��� ���-���� ���-����
���� ���� ���� ���� ��� ����� ����� � 6
:���� ��� ��� �����
��� ���� ��� ����� �����-�� ����� ���� � 7
����� ��� ��� ���� ���� ����� ����
:��-����
���-���� ���-���� ���� ����� ����� ����� � 8
:��� ���
����-�� ����� ���� ���� ���� ����� ����� � 9
:��-���� ����� ����� ���
��� ���� ������ ��� ����� ����� ����� � 10
:���-�� ����� ���� ����
��� ����� ��� ��� ���� ���� ����� ����� �� 11
����-�� ��-���� ��� ����� ��� ��� ��� ��
:��-����
��� ������ ��� ����� ��� ��� ���� ����� �� 12
����� ���� ������ ��-���� ��� ���-���
:���-��
:����� ��� ���-���� ���-���� �� 13
������ ����� ����� ���� ��� ����� ����� �� 14
�������� ���� ���� ����� ���� ���� ���
:����� ������
����-�� ����� ����� ����� ������ ���� �� 15
:��-����
�����-�� ������ ����� ���-�� ����� ���� �� 16
������ ���� �����-��� ���� ������ ����
:������� ��� �����
����� ����� ����� ����� ��� ���� �� 17
:����-��
���� ���� ��� ������� ������ ���� ����� �� 18
:���-�� ����� ���� ����
:����� ��� ���-���� ���-���� �� 19
���� ��� ��� ��� ���� ����� ����� ����� � 20
:����� ���� ���-�� ����-�� �����
���-�� ��� ������ ������-�� ����� ����� �� 21
��� ������ ���� ���� ��� ����� ����
:���-�� ����� ���� ������ ��� ���-��
����� ���� ��� ���� ����� ��� ����� �� 22
:���� ��� ����� ����� ����-��
:����� ��� ���-���� ���-���� �� 23
���� ����� ��� ��� ���� ���� ����� ����� �� 24
:��-���� ����� ���-����� ����
�����-��� ����� ���� ���-�� ����� ���� �� 25
����� ���� ������ ����� ���-�� ��� �����
:���-��
������� ������ ��� ���� ����� ����� �� 26
������ ����� ����� ��� ���� �����
:����-�� ���� ����-���� ����-����
��� ����� ���� ����� ����-�� ����� ����� �� 27
:��� ��� ����� ��� ���
���� ��� ����� ��� ����� ����� ��� ����� �� 28
����� ��� ���� ���� ����� ����-�� �����
:����-�� ����� ���-���� �����
��� ���-��-�� ��� ���� ��� ����� ����� �� 29
��-��� ���-��-��� ����-�� ���-�� ��� ���
:����� ���� ��� ��� ��� ��-���
���� ���� ����� ���-���� ���� ���-���� � 30
��� ���-��-�� ��� ��� ��-��� ����-��
:��-���� �����
��� ���-���� ��� ���-��-�� ����� ���� �� 31
:���� ��� ���-���� ��
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_latin8_crlf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_latin8_crlf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_latin8_crlf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,68 @@
+:���� ��� ����� �� ����� ��� ������ � 1
+���� ���-�� ���� ���� ��� ���� ����� � 2
+:���� ���-�� ����� ����� ����
+:���-���� ��� ��� ����� ����� � 3
+����� ����� ���-�� ����-�� ����� ���� � 4
+:���� ���� ���� ���
+���� ��� ����� ��� ���� ����� ����� � 5
+:��� ��� ���-���� ���-����
+���� ���� ���� ���� ��� ����� ����� � 6
+:���� ��� ��� �����
+��� ���� ��� ����� �����-�� ����� ���� � 7
+����� ��� ��� ���� ���� ����� ����
+:��-����
+���-���� ���-���� ���� ����� ����� ����� � 8
+:��� ���
+����-�� ����� ���� ���� ���� ����� ����� � 9
+:��-���� ����� ����� ���
+��� ���� ������ ��� ����� ����� ����� � 10
+:���-�� ����� ���� ����
+��� ����� ��� ��� ���� ���� ����� ����� �� 11
+����-�� ��-���� ��� ����� ��� ��� ��� ��
+:��-����
+��� ������ ��� ����� ��� ��� ���� ����� �� 12
+����� ���� ������ ��-���� ��� ���-���
+:���-��
+:����� ��� ���-���� ���-���� �� 13
+������ ����� ����� ���� ��� ����� ����� �� 14
+�������� ���� ���� ����� ���� ���� ���
+:����� ������
+����-�� ����� ����� ����� ������ ���� �� 15
+:��-����
+�����-�� ������ ����� ���-�� ����� ���� �� 16
+������ ���� �����-��� ���� ������ ����
+:������� ��� �����
+����� ����� ����� ����� ��� ���� �� 17
+:����-��
+���� ���� ��� ������� ������ ���� ����� �� 18
+:���-�� ����� ���� ����
+:����� ��� ���-���� ���-���� �� 19
+���� ��� ��� ��� ���� ����� ����� ����� � 20
+:����� ���� ���-�� ����-�� �����
+���-�� ��� ������ ������-�� ����� ����� �� 21
+��� ������ ���� ���� ��� ����� ����
+:���-�� ����� ���� ������ ��� ���-��
+����� ���� ��� ���� ����� ��� ����� �� 22
+:���� ��� ����� ����� ����-��
+:����� ��� ���-���� ���-���� �� 23
+���� ����� ��� ��� ���� ���� ����� ����� �� 24
+:��-���� ����� ���-����� ����
+�����-��� ����� ���� ���-�� ����� ���� �� 25
+����� ���� ������ ����� ���-�� ��� �����
+:���-��
+������� ������ ��� ���� ����� ����� �� 26
+������ ����� ����� ��� ���� �����
+:����-�� ���� ����-���� ����-����
+��� ����� ���� ����� ����-�� ����� ����� �� 27
+:��� ��� ����� ��� ���
+���� ��� ����� ��� ����� ����� ��� ����� �� 28
+����� ��� ���� ���� ����� ����-�� �����
+:����-�� ����� ���-���� �����
+��� ���-��-�� ��� ���� ��� ����� ����� �� 29
+��-��� ���-��-��� ����-�� ���-�� ��� ���
+:����� ���� ��� ��� ��� ��-���
+���� ���� ����� ���-���� ���� ���-���� � 30
+��� ���-��-�� ��� ��� ��-��� ����-��
+:��-���� �����
+��� ���-���� ��� ���-��-�� ����� ���� �� 31
+:���� ��� ���-���� ��
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_latin8_lf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_latin8_lf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_latin8_lf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,68 @@
+:���� ��� ����� �� ����� ��� ������ � 1
+���� ���-�� ���� ���� ��� ���� ����� � 2
+:���� ���-�� ����� ����� ����
+:���-���� ��� ��� ����� ����� � 3
+����� ����� ���-�� ����-�� ����� ���� � 4
+:���� ���� ���� ���
+���� ��� ����� ��� ���� ����� ����� � 5
+:��� ��� ���-���� ���-����
+���� ���� ���� ���� ��� ����� ����� � 6
+:���� ��� ��� �����
+��� ���� ��� ����� �����-�� ����� ���� � 7
+����� ��� ��� ���� ���� ����� ����
+:��-����
+���-���� ���-���� ���� ����� ����� ����� � 8
+:��� ���
+����-�� ����� ���� ���� ���� ����� ����� � 9
+:��-���� ����� ����� ���
+��� ���� ������ ��� ����� ����� ����� � 10
+:���-�� ����� ���� ����
+��� ����� ��� ��� ���� ���� ����� ����� �� 11
+����-�� ��-���� ��� ����� ��� ��� ��� ��
+:��-����
+��� ������ ��� ����� ��� ��� ���� ����� �� 12
+����� ���� ������ ��-���� ��� ���-���
+:���-��
+:����� ��� ���-���� ���-���� �� 13
+������ ����� ����� ���� ��� ����� ����� �� 14
+�������� ���� ���� ����� ���� ���� ���
+:����� ������
+����-�� ����� ����� ����� ������ ���� �� 15
+:��-����
+�����-�� ������ ����� ���-�� ����� ���� �� 16
+������ ���� �����-��� ���� ������ ����
+:������� ��� �����
+����� ����� ����� ����� ��� ���� �� 17
+:����-��
+���� ���� ��� ������� ������ ���� ����� �� 18
+:���-�� ����� ���� ����
+:����� ��� ���-���� ���-���� �� 19
+���� ��� ��� ��� ���� ����� ����� ����� � 20
+:����� ���� ���-�� ����-�� �����
+���-�� ��� ������ ������-�� ����� ����� �� 21
+��� ������ ���� ���� ��� ����� ����
+:���-�� ����� ���� ������ ��� ���-��
+����� ���� ��� ���� ����� ��� ����� �� 22
+:���� ��� ����� ����� ����-��
+:����� ��� ���-���� ���-���� �� 23
+���� ����� ��� ��� ���� ���� ����� ����� �� 24
+:��-���� ����� ���-����� ����
+�����-��� ����� ���� ���-�� ����� ���� �� 25
+����� ���� ������ ����� ���-�� ��� �����
+:���-��
+������� ������ ��� ���� ����� ����� �� 26
+������ ����� ����� ��� ���� �����
+:����-�� ���� ����-���� ����-����
+��� ����� ���� ����� ����-�� ����� ����� �� 27
+:��� ��� ����� ��� ���
+���� ��� ����� ��� ����� ����� ��� ����� �� 28
+����� ��� ���� ���� ����� ����-�� �����
+:����-�� ����� ���-���� �����
+��� ���-��-�� ��� ���� ��� ����� ����� �� 29
+��-��� ���-��-��� ����-�� ���-�� ��� ���
+:����� ���� ��� ��� ��� ��-���
+���� ���� ����� ���-���� ���� ���-���� � 30
+��� ���-��-�� ��� ��� ��-��� ����-��
+:��-���� �����
+��� ���-���� ��� ���-��-�� ����� ���� �� 31
+:���� ��� ���-���� ��
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_utf8_cr.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_utf8_cr.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_utf8_cr.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1 @@
+:ץראה תאו םימשה תא םיהלא ארב תישארב א 1
םוהת ינפ-לע ךשחו והבו והת התיה ץראהו ב 2
:םימה ינפ-לע תפחרמ םיהלא חורו
:רוא-יהיו רוא יהי םיהלא רמאיו ג 3
םיהלא לדביו בוט-יכ רואה-תא םיהלא אריו ד 4
:ךשחה ןיבו רואה ןיב
הליל ארק ךשחלו םוי רואל םיהלא ארקיו ה 5
:דחא םוי רקב-יהיו ברע-יהיו
יהיו םימה ךותב עיקר יהי םיהלא רמאיו ו 6
:םימל םימ ןיב לידבמ
רשא םימה ןיב לדביו עיקרה-תא םיהלא שעיו ז 7
עיקרל לעמ רשא םימה ןיבו עיקרל תחתמ
:ןכ-יהיו
רקב-יהיו ברע-יהיו םימש עיקרל םיהלא ארקיו ח 8
:ינש םוי
םוקמ-לא םימשה תחתמ םימה ווקי םיהלא רמאיו ט 9
:ןכ-יהיו השביה הארתו דחא
ארק םימה הוקמלו ץרא השביל םיהלא ארקיו י 10
:בוט-יכ םיהלא אריו םימי
ערז עירזמ בשע אשד ץראה אשדת םיהלא רמאיו אי 11
ץראה-לע וב-וערז רשא ונימל ירפ השע ירפ ץע
:ןכ-יהיו
ץעו והנימל ערז עירזמ בשע אשד ץראה אצותו בי 12
םיהלא אריו והנימל וב-וערז רשא ירפ-השע
:בוט-יכ
:ישילש םוי רקב-יהיו ברע-יהיו גי 13
לידבהל םימשה עיקרב תראמ יהי םיהלא רמאיו די 14
םידעומלו תתאל ויהו הלילה ןיבו םויה ןיב
:םינשו םימילו
ץראה-לע ריאהל םימשה עיקרב תרואמל ויהו וט 15
:ןכ-יהיו
רואמה-תא םילדגה תראמה ינש-תא םיהלא שעיו זט 16
תלשממל ןטקה רואמה-תאו םויה תלשממל לדגה
:םיבכוכה תאו הלילה
ריאהל םימשה עיקרב םיהלא םתא ןתיו זי 17
:ץראה-לע
ןיבו רואה ןיב לידבהלו הלילבו םויב לשמלו חי 18
:בוט-יכ םיהלא אריו ךשחה
:יעיבר םוי רקב-יהיו ברע-יהיו טי 19
ףועו היח שפנ ץרש םימה וצרשי םיהלא רמאיו כ 20
:םימשה עיקר ינפ-לע ץראה-לע ףפועי
שפנ-לכ תאו םילדגה םנינתה-תא םיהלא ארביו אכ 21
תאו םהנימל םימה וצרש רשא תשמרה היחה
:בוט-יכ םיהלא אריו והנימל ףנכ ףוע-לכ
ואלמו וברו ורפ רמאל םיהלא םתא ךרביו בכ 22
:ץראב ברי ףועהו םימיב םימה-תא
:ישימח םוי רקב-יהיו ברע-יהיו גכ 23
המהב הנימל היח שפנ ץראה אצות םיהלא רמאיו דכ 24
:ןכ-יהיו הנימל ץרא-ותיחו שמרו
המהבה-תאו הנימל ץראה תיח-תא םיהלא שעיו הכ 25
םיהלא אריו והנימל המדאה שמר-לכ תאו הנימל
:בוט-יכ
ונתומדכ ונמלצב םדא השענ םיהלא רמאיו וכ 26
המהבבו םימשה ףועבו םיה תגדב ודריו
:ץראה-לע שמרה שמרה-לכבו ץראה-לכבו
ארב םיהלא םלצב ומלצב םדאה-תא םיהלא ארביו זכ 27
:םתא ארב הבקנו רכז ותא
וברו ורפ םיהלא םהל רמאיו םיהלא םתא ךרביו חכ 28
ףועבו םיה תגדב ודרו השבכו ץראה-תא ואלמו
:ץראה-לע תשמרה היח-לכבו םימשה
ערז בשע-לכ-תא םכל יתתנ הנה םיהלא רמאיו טכ 29
וב-רשא ץעה-לכ-תאו ץראה-לכ ינפ-לע רשא ערז
:הלכאל היהי םכל ערז ערז ץע-ירפ
שמור לכלו םימשה ףוע-לכלו ץראה תיח-לכלו ל 30
בשע קרי-לכ-תא היח שפנ וב-רשא ץראה-לע
:ןכ-יהיו הלכאל
דאמ בוט-הנהו השע רשא-לכ-תא םיהלא אריו אל 31
:יששה םוי רקב-יהיו בר
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_utf8_crlf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_utf8_crlf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_utf8_crlf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,68 @@
+:ץראה תאו םימשה תא םיהלא ארב תישארב א 1
+םוהת ינפ-לע ךשחו והבו והת התיה ץראהו ב 2
+:םימה ינפ-לע תפחרמ םיהלא חורו
+:רוא-יהיו רוא יהי םיהלא רמאיו ג 3
+םיהלא לדביו בוט-יכ רואה-תא םיהלא אריו ד 4
+:ךשחה ןיבו רואה ןיב
+הליל ארק ךשחלו םוי רואל םיהלא ארקיו ה 5
+:דחא םוי רקב-יהיו ברע-יהיו
+יהיו םימה ךותב עיקר יהי םיהלא רמאיו ו 6
+:םימל םימ ןיב לידבמ
+רשא םימה ןיב לדביו עיקרה-תא םיהלא שעיו ז 7
+עיקרל לעמ רשא םימה ןיבו עיקרל תחתמ
+:ןכ-יהיו
+רקב-יהיו ברע-יהיו םימש עיקרל םיהלא ארקיו ח 8
+:ינש םוי
+םוקמ-לא םימשה תחתמ םימה ווקי םיהלא רמאיו ט 9
+:ןכ-יהיו השביה הארתו דחא
+ארק םימה הוקמלו ץרא השביל םיהלא ארקיו י 10
+:בוט-יכ םיהלא אריו םימי
+ערז עירזמ בשע אשד ץראה אשדת םיהלא רמאיו אי 11
+ץראה-לע וב-וערז רשא ונימל ירפ השע ירפ ץע
+:ןכ-יהיו
+ץעו והנימל ערז עירזמ בשע אשד ץראה אצותו בי 12
+םיהלא אריו והנימל וב-וערז רשא ירפ-השע
+:בוט-יכ
+:ישילש םוי רקב-יהיו ברע-יהיו גי 13
+לידבהל םימשה עיקרב תראמ יהי םיהלא רמאיו די 14
+םידעומלו תתאל ויהו הלילה ןיבו םויה ןיב
+:םינשו םימילו
+ץראה-לע ריאהל םימשה עיקרב תרואמל ויהו וט 15
+:ןכ-יהיו
+רואמה-תא םילדגה תראמה ינש-תא םיהלא שעיו זט 16
+תלשממל ןטקה רואמה-תאו םויה תלשממל לדגה
+:םיבכוכה תאו הלילה
+ריאהל םימשה עיקרב םיהלא םתא ןתיו זי 17
+:ץראה-לע
+ןיבו רואה ןיב לידבהלו הלילבו םויב לשמלו חי 18
+:בוט-יכ םיהלא אריו ךשחה
+:יעיבר םוי רקב-יהיו ברע-יהיו טי 19
+ףועו היח שפנ ץרש םימה וצרשי םיהלא רמאיו כ 20
+:םימשה עיקר ינפ-לע ץראה-לע ףפועי
+שפנ-לכ תאו םילדגה םנינתה-תא םיהלא ארביו אכ 21
+תאו םהנימל םימה וצרש רשא תשמרה היחה
+:בוט-יכ םיהלא אריו והנימל ףנכ ףוע-לכ
+ואלמו וברו ורפ רמאל םיהלא םתא ךרביו בכ 22
+:ץראב ברי ףועהו םימיב םימה-תא
+:ישימח םוי רקב-יהיו ברע-יהיו גכ 23
+המהב הנימל היח שפנ ץראה אצות םיהלא רמאיו דכ 24
+:ןכ-יהיו הנימל ץרא-ותיחו שמרו
+המהבה-תאו הנימל ץראה תיח-תא םיהלא שעיו הכ 25
+םיהלא אריו והנימל המדאה שמר-לכ תאו הנימל
+:בוט-יכ
+ונתומדכ ונמלצב םדא השענ םיהלא רמאיו וכ 26
+המהבבו םימשה ףועבו םיה תגדב ודריו
+:ץראה-לע שמרה שמרה-לכבו ץראה-לכבו
+ארב םיהלא םלצב ומלצב םדאה-תא םיהלא ארביו זכ 27
+:םתא ארב הבקנו רכז ותא
+וברו ורפ םיהלא םהל רמאיו םיהלא םתא ךרביו חכ 28
+ףועבו םיה תגדב ודרו השבכו ץראה-תא ואלמו
+:ץראה-לע תשמרה היח-לכבו םימשה
+ערז בשע-לכ-תא םכל יתתנ הנה םיהלא רמאיו טכ 29
+וב-רשא ץעה-לכ-תאו ץראה-לכ ינפ-לע רשא ערז
+:הלכאל היהי םכל ערז ערז ץע-ירפ
+שמור לכלו םימשה ףוע-לכלו ץראה תיח-לכלו ל 30
+בשע קרי-לכ-תא היח שפנ וב-רשא ץראה-לע
+:ןכ-יהיו הלכאל
+דאמ בוט-הנהו השע רשא-לכ-תא םיהלא אריו אל 31
+:יששה םוי רקב-יהיו בר
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_utf8_lf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_utf8_lf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/hebrew_utf8_lf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,68 @@
+:ץראה תאו םימשה תא םיהלא ארב תישארב א 1
+םוהת ינפ-לע ךשחו והבו והת התיה ץראהו ב 2
+:םימה ינפ-לע תפחרמ םיהלא חורו
+:רוא-יהיו רוא יהי םיהלא רמאיו ג 3
+םיהלא לדביו בוט-יכ רואה-תא םיהלא אריו ד 4
+:ךשחה ןיבו רואה ןיב
+הליל ארק ךשחלו םוי רואל םיהלא ארקיו ה 5
+:דחא םוי רקב-יהיו ברע-יהיו
+יהיו םימה ךותב עיקר יהי םיהלא רמאיו ו 6
+:םימל םימ ןיב לידבמ
+רשא םימה ןיב לדביו עיקרה-תא םיהלא שעיו ז 7
+עיקרל לעמ רשא םימה ןיבו עיקרל תחתמ
+:ןכ-יהיו
+רקב-יהיו ברע-יהיו םימש עיקרל םיהלא ארקיו ח 8
+:ינש םוי
+םוקמ-לא םימשה תחתמ םימה ווקי םיהלא רמאיו ט 9
+:ןכ-יהיו השביה הארתו דחא
+ארק םימה הוקמלו ץרא השביל םיהלא ארקיו י 10
+:בוט-יכ םיהלא אריו םימי
+ערז עירזמ בשע אשד ץראה אשדת םיהלא רמאיו אי 11
+ץראה-לע וב-וערז רשא ונימל ירפ השע ירפ ץע
+:ןכ-יהיו
+ץעו והנימל ערז עירזמ בשע אשד ץראה אצותו בי 12
+םיהלא אריו והנימל וב-וערז רשא ירפ-השע
+:בוט-יכ
+:ישילש םוי רקב-יהיו ברע-יהיו גי 13
+לידבהל םימשה עיקרב תראמ יהי םיהלא רמאיו די 14
+םידעומלו תתאל ויהו הלילה ןיבו םויה ןיב
+:םינשו םימילו
+ץראה-לע ריאהל םימשה עיקרב תרואמל ויהו וט 15
+:ןכ-יהיו
+רואמה-תא םילדגה תראמה ינש-תא םיהלא שעיו זט 16
+תלשממל ןטקה רואמה-תאו םויה תלשממל לדגה
+:םיבכוכה תאו הלילה
+ריאהל םימשה עיקרב םיהלא םתא ןתיו זי 17
+:ץראה-לע
+ןיבו רואה ןיב לידבהלו הלילבו םויב לשמלו חי 18
+:בוט-יכ םיהלא אריו ךשחה
+:יעיבר םוי רקב-יהיו ברע-יהיו טי 19
+ףועו היח שפנ ץרש םימה וצרשי םיהלא רמאיו כ 20
+:םימשה עיקר ינפ-לע ץראה-לע ףפועי
+שפנ-לכ תאו םילדגה םנינתה-תא םיהלא ארביו אכ 21
+תאו םהנימל םימה וצרש רשא תשמרה היחה
+:בוט-יכ םיהלא אריו והנימל ףנכ ףוע-לכ
+ואלמו וברו ורפ רמאל םיהלא םתא ךרביו בכ 22
+:ץראב ברי ףועהו םימיב םימה-תא
+:ישימח םוי רקב-יהיו ברע-יהיו גכ 23
+המהב הנימל היח שפנ ץראה אצות םיהלא רמאיו דכ 24
+:ןכ-יהיו הנימל ץרא-ותיחו שמרו
+המהבה-תאו הנימל ץראה תיח-תא םיהלא שעיו הכ 25
+םיהלא אריו והנימל המדאה שמר-לכ תאו הנימל
+:בוט-יכ
+ונתומדכ ונמלצב םדא השענ םיהלא רמאיו וכ 26
+המהבבו םימשה ףועבו םיה תגדב ודריו
+:ץראה-לע שמרה שמרה-לכבו ץראה-לכבו
+ארב םיהלא םלצב ומלצב םדאה-תא םיהלא ארביו זכ 27
+:םתא ארב הבקנו רכז ותא
+וברו ורפ םיהלא םהל רמאיו םיהלא םתא ךרביו חכ 28
+ףועבו םיה תגדב ודרו השבכו ץראה-תא ואלמו
+:ץראה-לע תשמרה היח-לכבו םימשה
+ערז בשע-לכ-תא םכל יתתנ הנה םיהלא רמאיו טכ 29
+וב-רשא ץעה-לכ-תאו ץראה-לכ ינפ-לע רשא ערז
+:הלכאל היהי םכל ערז ערז ץע-ירפ
+שמור לכלו םימשה ףוע-לכלו ץראה תיח-לכלו ל 30
+בשע קרי-לכ-תא היח שפנ וב-רשא ץראה-לע
+:ןכ-יהיו הלכאל
+דאמ בוט-הנהו השע רשא-לכ-תא םיהלא אריו אל 31
+:יששה םוי רקב-יהיו בר
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_cp1252_cr.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_cp1252_cr.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_cp1252_cr.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1 @@
+Als Gregor Samsa eines Morgens aus unruhigen Tr�umen erwachte, fand er sich in seinem Bett zu einem ungeheueren Ungeziefer verwandelt. Er lag auf seinem panzerartig harten R�cken und sah, wenn er den Kopf ein wenig hob, seinen gew�lbten, braunen, von bogenf�rmigen Versteifungen geteilten Bauch, auf dessen H�he sich die Bettdecke, zum g�nzlichen Niedergleiten bereit, kaum noch erhalten konnte. Seine vielen, im Vergleich zu seinem sonstigen Umfang kl�glich d�nnen Beine flimmerten ihm hilflos vor den Augen.
�Was ist mit mir geschehen?�, dachte er. Es war kein Traum. Sein Zimmer, ein richtiges, nur etwas zu kleines Menschenzimmer, lag ruhig zwischen den vier wohlbekannten W�nden. �ber dem Tisch, auf dem eine auseinandergepackte Musterkollektion von Tuchwaren ausgebreitet war - Samsa war Reisender - hing das Bild, das er vor kurzem aus einer illustrierten Zeitschrift ausgeschnitten und in einem h�bschen, vergoldeten Rahmen untergebracht hatte. Es stellte eine Dame dar, die mit einem Pelzhut und einer Pelzboa versehen, aufrecht dasa� und einen schweren Pelzmuff, in dem ihr ganzer Unterarm verschwunden war, dem Beschauer entgegenhob.
Gregors Blick richtete sich dann zum Fenster, und das tr�be Wetter - man h�rte Regentropfen auf das Fensterblech aufschlagen - machte ihn ganz melancholisch. �Wie w�re es, wenn ich noch ein wenig weiterschliefe und alle Narrheiten verg��e�, dachte er, aber das war g�nzlich undurchf�hrbar, denn er war gew�hnt, auf der rechten Seite zu schlafen, konnte sich aber in seinem gegenw�rtigen Zustand nicht in diese Lage bringen. Mit welcher Kraft er sich auch auf die rechte Seite warf, immer wieder schaukelte er in die R�ckenlage zur�ck. Er versuchte es wohl hundertmal, schlo� die Augen, um die zappelnden Beine nicht sehen zu m�ssen, und lie� erst ab, als er in der Seite einen noch nie gef�hlten, leichten, dumpfen Schmerz zu f�hlen begann.
�Ach Gott�, dachte er, �was f�r einen anstrengenden Beruf habe ich gew�hlt! Tag aus, Tag ein auf der Reise. Die gesch�ftlichen Aufregungen sind viel gr��er, als im eigentlichen Gesch�ft zu Hause, und au�erdem ist mir noch diese Plage des Reisens auferlegt, die Sorgen um die Zuganschl�sse, das unregelm��ige, schlechte Essen, ein immer wechselnder, nie andauernder, nie herzlich werdender menschlicher Verkehr. Der Teufel soll das alles holen!� Er f�hlte ein leichtes Jucken oben auf dem Bauch; schob sich auf dem R�cken langsam n�her zum Bettpfosten, um den Kopf besser heben zu k�nnen; fand die juckende Stelle, die mit lauter kleinen wei�en P�nktchen besetzt war, die er nicht zu beurteilen verstand; und wollte mit einem Bein die Stelle betasten, zog es aber gleich zur�ck, denn bei der Ber�hrung umwehten ihn K�lteschauer.
Er glitt wieder in seine fr�here Lage zur�ck. �Dies fr�hzeitige Aufstehen�, dachte er, �macht einen ganz bl�dsinnig. Der Mensch mu� seinen Schlaf haben. Andere Reisende leben wie Haremsfrauen. Wenn ich zum Beispiel im Laufe des Vormittags ins Gasthaus zur�ckgehe, um die erlangten Auftr�ge zu �berschreiben, sitzen diese Herren erst beim Fr�hst�ck. Das sollte ich bei meinem Chef versuchen; ich w�rde auf der Stelle hinausfliegen. Wer wei� �brigens, ob das nicht sehr gut f�r mich w�re. Wenn ich mich nicht wegen meiner Eltern zur�ckhielte, ich h�tte l�ngst gek�ndigt, ich w�re vor den Chef hin getreten und h�tte ihm meine Meinung von Grund des Herzens aus gesagt. Vom Pult h�tte er fallen m�ssen! Es ist auch eine sonderbare Art, sich auf das Pult zu setzen und von der H�he herab mit dem Angestellten zu reden, der �berdies wegen der Schwerh�rigkeit des Chefs ganz nahe herantreten mu�. Nun, die Hoffnung ist noch nicht g�nzlich aufgegeben; habe ich einmal das Geld beisammen, um die Schuld der Eltern an ihn abzuzahlen - es d�rfte noch f�nf bis sechs Jahre dauern - , mache ich die Sache unbedingt. Dann wird der gro�e Schnitt gemacht. Vorl�ufig allerdings mu� ich aufstehen, denn mein Zug f�hrt um f�nf.�
Und er sah zur Weckuhr hin�ber, die auf dem Kasten tickte. �Himmlischer Vater!�, dachte er. Es war halb sieben Uhr, und die Zeiger gingen ruhig vorw�rts, es war sogar halb vor�ber, es n�herte sich schon dreiviertel. Sollte der Wecker nicht gel�utet haben? Man sah vom Bett aus, da� er auf vier Uhr richtig eingestellt war; gewi� hatte er auch gel�utet. Ja, aber war es m�glich, dieses m�belersch�tternde L�uten ruhig zu verschlafen? Nun, ruhig hatte er ja nicht geschlafen, aber wahrscheinlich desto fester. Was aber sollte er jetzt tun? Der n�chste Zug ging um sieben Uhr; um den einzuholen, h�tte er sich unsinnig beeilen m�ssen, und die Kollektion war noch nicht eingepackt, und er selbst f�hlte sich durchaus nicht besonders frisch und beweglich. Und selbst wenn er den Zug einholte, ein Donnerwetter des Chefs war nicht zu vermeiden, denn der Gesch�ftsdiener hatte beim F�nfuhrzug gewartet und die Meldung von seiner Vers�umnis l�ngst erstattet. Es war eine Kreatur des Chefs, ohne R�ckgrat und Verstand. Wie nun, wenn er sich krank meldete? Das w�re aber �u�erst peinlich und verd�chtig, denn Gregor war w�hrend seines f�nfj�hrigen Dienstes noch nicht einmal krank gewesen. Gewi� w�rde der Chef mit dem Krankenkassenarzt kommen, w�rde den Eltern wegen des faulen Sohnes Vorw�rfe machen und alle Einw�nde durch den Hinweis auf den Krankenkassenarzt abschneiden, f�r den es ja �berhaupt nur ganz gesunde, aber arbeitsscheue Menschen gibt. Und h�tte er �brigens in diesem Falle so ganz unrecht? Gregor f�hlte sich tats�chlich, abgesehen von einer nach dem langen Schlaf wirklich �berfl�ssigen Schl�frigkeit, ganz wohl und hatte sogar einen besonders kr�ftigen Hunger.
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_cp1252_crlf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_cp1252_crlf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_cp1252_crlf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,11 @@
+Als Gregor Samsa eines Morgens aus unruhigen Tr�umen erwachte, fand er sich in seinem Bett zu einem ungeheueren Ungeziefer verwandelt. Er lag auf seinem panzerartig harten R�cken und sah, wenn er den Kopf ein wenig hob, seinen gew�lbten, braunen, von bogenf�rmigen Versteifungen geteilten Bauch, auf dessen H�he sich die Bettdecke, zum g�nzlichen Niedergleiten bereit, kaum noch erhalten konnte. Seine vielen, im Vergleich zu seinem sonstigen Umfang kl�glich d�nnen Beine flimmerten ihm hilflos vor den Augen.
+
+�Was ist mit mir geschehen?�, dachte er. Es war kein Traum. Sein Zimmer, ein richtiges, nur etwas zu kleines Menschenzimmer, lag ruhig zwischen den vier wohlbekannten W�nden. �ber dem Tisch, auf dem eine auseinandergepackte Musterkollektion von Tuchwaren ausgebreitet war - Samsa war Reisender - hing das Bild, das er vor kurzem aus einer illustrierten Zeitschrift ausgeschnitten und in einem h�bschen, vergoldeten Rahmen untergebracht hatte. Es stellte eine Dame dar, die mit einem Pelzhut und einer Pelzboa versehen, aufrecht dasa� und einen schweren Pelzmuff, in dem ihr ganzer Unterarm verschwunden war, dem Beschauer entgegenhob.
+
+Gregors Blick richtete sich dann zum Fenster, und das tr�be Wetter - man h�rte Regentropfen auf das Fensterblech aufschlagen - machte ihn ganz melancholisch. �Wie w�re es, wenn ich noch ein wenig weiterschliefe und alle Narrheiten verg��e�, dachte er, aber das war g�nzlich undurchf�hrbar, denn er war gew�hnt, auf der rechten Seite zu schlafen, konnte sich aber in seinem gegenw�rtigen Zustand nicht in diese Lage bringen. Mit welcher Kraft er sich auch auf die rechte Seite warf, immer wieder schaukelte er in die R�ckenlage zur�ck. Er versuchte es wohl hundertmal, schlo� die Augen, um die zappelnden Beine nicht sehen zu m�ssen, und lie� erst ab, als er in der Seite einen noch nie gef�hlten, leichten, dumpfen Schmerz zu f�hlen begann.
+
+�Ach Gott�, dachte er, �was f�r einen anstrengenden Beruf habe ich gew�hlt! Tag aus, Tag ein auf der Reise. Die gesch�ftlichen Aufregungen sind viel gr��er, als im eigentlichen Gesch�ft zu Hause, und au�erdem ist mir noch diese Plage des Reisens auferlegt, die Sorgen um die Zuganschl�sse, das unregelm��ige, schlechte Essen, ein immer wechselnder, nie andauernder, nie herzlich werdender menschlicher Verkehr. Der Teufel soll das alles holen!� Er f�hlte ein leichtes Jucken oben auf dem Bauch; schob sich auf dem R�cken langsam n�her zum Bettpfosten, um den Kopf besser heben zu k�nnen; fand die juckende Stelle, die mit lauter kleinen wei�en P�nktchen besetzt war, die er nicht zu beurteilen verstand; und wollte mit einem Bein die Stelle betasten, zog es aber gleich zur�ck, denn bei der Ber�hrung umwehten ihn K�lteschauer.
+
+Er glitt wieder in seine fr�here Lage zur�ck. �Dies fr�hzeitige Aufstehen�, dachte er, �macht einen ganz bl�dsinnig. Der Mensch mu� seinen Schlaf haben. Andere Reisende leben wie Haremsfrauen. Wenn ich zum Beispiel im Laufe des Vormittags ins Gasthaus zur�ckgehe, um die erlangten Auftr�ge zu �berschreiben, sitzen diese Herren erst beim Fr�hst�ck. Das sollte ich bei meinem Chef versuchen; ich w�rde auf der Stelle hinausfliegen. Wer wei� �brigens, ob das nicht sehr gut f�r mich w�re. Wenn ich mich nicht wegen meiner Eltern zur�ckhielte, ich h�tte l�ngst gek�ndigt, ich w�re vor den Chef hin getreten und h�tte ihm meine Meinung von Grund des Herzens aus gesagt. Vom Pult h�tte er fallen m�ssen! Es ist auch eine sonderbare Art, sich auf das Pult zu setzen und von der H�he herab mit dem Angestellten zu reden, der �berdies wegen der Schwerh�rigkeit des Chefs ganz nahe herantreten mu�. Nun, die Hoffnung ist noch nicht g�nzlich aufgegeben; habe ich einmal das Geld beisammen, um die Schuld der Eltern an ihn abzuzahlen - es d�rfte noch f�nf bis sechs Jahre dauern - , mache ich die Sache unbedingt. Dann wird der gro�e Schnitt gemacht. Vorl�ufig allerdings mu� ich aufstehen, denn mein Zug f�hrt um f�nf.�
+
+Und er sah zur Weckuhr hin�ber, die auf dem Kasten tickte. �Himmlischer Vater!�, dachte er. Es war halb sieben Uhr, und die Zeiger gingen ruhig vorw�rts, es war sogar halb vor�ber, es n�herte sich schon dreiviertel. Sollte der Wecker nicht gel�utet haben? Man sah vom Bett aus, da� er auf vier Uhr richtig eingestellt war; gewi� hatte er auch gel�utet. Ja, aber war es m�glich, dieses m�belersch�tternde L�uten ruhig zu verschlafen? Nun, ruhig hatte er ja nicht geschlafen, aber wahrscheinlich desto fester. Was aber sollte er jetzt tun? Der n�chste Zug ging um sieben Uhr; um den einzuholen, h�tte er sich unsinnig beeilen m�ssen, und die Kollektion war noch nicht eingepackt, und er selbst f�hlte sich durchaus nicht besonders frisch und beweglich. Und selbst wenn er den Zug einholte, ein Donnerwetter des Chefs war nicht zu vermeiden, denn der Gesch�ftsdiener hatte beim F�nfuhrzug gewartet und die Meldung von seiner Vers�umnis l�ngst erstattet. Es war eine Kreatur des Chefs, ohne R�ckgrat und Verstand. Wie nun, wenn er sich krank meldete? Das w�re aber �u�erst peinlich und verd�chtig, denn Gregor war w�hrend seines f�nfj�hrigen Dienstes noch nicht einmal krank gewesen. Gewi� w�rde der Chef mit dem Krankenkassenarzt kommen, w�rde den Eltern wegen des faulen Sohnes Vorw�rfe machen und alle Einw�nde durch den Hinweis auf den Krankenkassenarzt abschneiden, f�r den es ja �berhaupt nur ganz gesunde, aber arbeitsscheue Menschen gibt. Und h�tte er �brigens in diesem Falle so ganz unrecht? Gregor f�hlte sich tats�chlich, abgesehen von einer nach dem langen Schlaf wirklich �berfl�ssigen Schl�frigkeit, ganz wohl und hatte sogar einen besonders kr�ftigen Hunger.
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_cp1252_lf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_cp1252_lf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_cp1252_lf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,11 @@
+Als Gregor Samsa eines Morgens aus unruhigen Tr�umen erwachte, fand er sich in seinem Bett zu einem ungeheueren Ungeziefer verwandelt. Er lag auf seinem panzerartig harten R�cken und sah, wenn er den Kopf ein wenig hob, seinen gew�lbten, braunen, von bogenf�rmigen Versteifungen geteilten Bauch, auf dessen H�he sich die Bettdecke, zum g�nzlichen Niedergleiten bereit, kaum noch erhalten konnte. Seine vielen, im Vergleich zu seinem sonstigen Umfang kl�glich d�nnen Beine flimmerten ihm hilflos vor den Augen.
+
+�Was ist mit mir geschehen?�, dachte er. Es war kein Traum. Sein Zimmer, ein richtiges, nur etwas zu kleines Menschenzimmer, lag ruhig zwischen den vier wohlbekannten W�nden. �ber dem Tisch, auf dem eine auseinandergepackte Musterkollektion von Tuchwaren ausgebreitet war - Samsa war Reisender - hing das Bild, das er vor kurzem aus einer illustrierten Zeitschrift ausgeschnitten und in einem h�bschen, vergoldeten Rahmen untergebracht hatte. Es stellte eine Dame dar, die mit einem Pelzhut und einer Pelzboa versehen, aufrecht dasa� und einen schweren Pelzmuff, in dem ihr ganzer Unterarm verschwunden war, dem Beschauer entgegenhob.
+
+Gregors Blick richtete sich dann zum Fenster, und das tr�be Wetter - man h�rte Regentropfen auf das Fensterblech aufschlagen - machte ihn ganz melancholisch. �Wie w�re es, wenn ich noch ein wenig weiterschliefe und alle Narrheiten verg��e�, dachte er, aber das war g�nzlich undurchf�hrbar, denn er war gew�hnt, auf der rechten Seite zu schlafen, konnte sich aber in seinem gegenw�rtigen Zustand nicht in diese Lage bringen. Mit welcher Kraft er sich auch auf die rechte Seite warf, immer wieder schaukelte er in die R�ckenlage zur�ck. Er versuchte es wohl hundertmal, schlo� die Augen, um die zappelnden Beine nicht sehen zu m�ssen, und lie� erst ab, als er in der Seite einen noch nie gef�hlten, leichten, dumpfen Schmerz zu f�hlen begann.
+
+�Ach Gott�, dachte er, �was f�r einen anstrengenden Beruf habe ich gew�hlt! Tag aus, Tag ein auf der Reise. Die gesch�ftlichen Aufregungen sind viel gr��er, als im eigentlichen Gesch�ft zu Hause, und au�erdem ist mir noch diese Plage des Reisens auferlegt, die Sorgen um die Zuganschl�sse, das unregelm��ige, schlechte Essen, ein immer wechselnder, nie andauernder, nie herzlich werdender menschlicher Verkehr. Der Teufel soll das alles holen!� Er f�hlte ein leichtes Jucken oben auf dem Bauch; schob sich auf dem R�cken langsam n�her zum Bettpfosten, um den Kopf besser heben zu k�nnen; fand die juckende Stelle, die mit lauter kleinen wei�en P�nktchen besetzt war, die er nicht zu beurteilen verstand; und wollte mit einem Bein die Stelle betasten, zog es aber gleich zur�ck, denn bei der Ber�hrung umwehten ihn K�lteschauer.
+
+Er glitt wieder in seine fr�here Lage zur�ck. �Dies fr�hzeitige Aufstehen�, dachte er, �macht einen ganz bl�dsinnig. Der Mensch mu� seinen Schlaf haben. Andere Reisende leben wie Haremsfrauen. Wenn ich zum Beispiel im Laufe des Vormittags ins Gasthaus zur�ckgehe, um die erlangten Auftr�ge zu �berschreiben, sitzen diese Herren erst beim Fr�hst�ck. Das sollte ich bei meinem Chef versuchen; ich w�rde auf der Stelle hinausfliegen. Wer wei� �brigens, ob das nicht sehr gut f�r mich w�re. Wenn ich mich nicht wegen meiner Eltern zur�ckhielte, ich h�tte l�ngst gek�ndigt, ich w�re vor den Chef hin getreten und h�tte ihm meine Meinung von Grund des Herzens aus gesagt. Vom Pult h�tte er fallen m�ssen! Es ist auch eine sonderbare Art, sich auf das Pult zu setzen und von der H�he herab mit dem Angestellten zu reden, der �berdies wegen der Schwerh�rigkeit des Chefs ganz nahe herantreten mu�. Nun, die Hoffnung ist noch nicht g�nzlich aufgegeben; habe ich einmal das Geld beisammen, um die Schuld der Eltern an ihn abzuzahlen - es d�rfte noch f�nf bis sechs Jahre dauern - , mache ich die Sache unbedingt. Dann wird der gro�e Schnitt gemacht. Vorl�ufig allerdings mu� ich aufstehen, denn mein Zug f�hrt um f�nf.�
+
+Und er sah zur Weckuhr hin�ber, die auf dem Kasten tickte. �Himmlischer Vater!�, dachte er. Es war halb sieben Uhr, und die Zeiger gingen ruhig vorw�rts, es war sogar halb vor�ber, es n�herte sich schon dreiviertel. Sollte der Wecker nicht gel�utet haben? Man sah vom Bett aus, da� er auf vier Uhr richtig eingestellt war; gewi� hatte er auch gel�utet. Ja, aber war es m�glich, dieses m�belersch�tternde L�uten ruhig zu verschlafen? Nun, ruhig hatte er ja nicht geschlafen, aber wahrscheinlich desto fester. Was aber sollte er jetzt tun? Der n�chste Zug ging um sieben Uhr; um den einzuholen, h�tte er sich unsinnig beeilen m�ssen, und die Kollektion war noch nicht eingepackt, und er selbst f�hlte sich durchaus nicht besonders frisch und beweglich. Und selbst wenn er den Zug einholte, ein Donnerwetter des Chefs war nicht zu vermeiden, denn der Gesch�ftsdiener hatte beim F�nfuhrzug gewartet und die Meldung von seiner Vers�umnis l�ngst erstattet. Es war eine Kreatur des Chefs, ohne R�ckgrat und Verstand. Wie nun, wenn er sich krank meldete? Das w�re aber �u�erst peinlich und verd�chtig, denn Gregor war w�hrend seines f�nfj�hrigen Dienstes noch nicht einmal krank gewesen. Gewi� w�rde der Chef mit dem Krankenkassenarzt kommen, w�rde den Eltern wegen des faulen Sohnes Vorw�rfe machen und alle Einw�nde durch den Hinweis auf den Krankenkassenarzt abschneiden, f�r den es ja �berhaupt nur ganz gesunde, aber arbeitsscheue Menschen gibt. Und h�tte er �brigens in diesem Falle so ganz unrecht? Gregor f�hlte sich tats�chlich, abgesehen von einer nach dem langen Schlaf wirklich �berfl�ssigen Schl�frigkeit, ganz wohl und hatte sogar einen besonders kr�ftigen Hunger.
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_latin1_cr.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_latin1_cr.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_latin1_cr.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1 @@
+Als Gregor Samsa eines Morgens aus unruhigen Tr�umen erwachte, fand er sich in seinem Bett zu einem ungeheueren Ungeziefer verwandelt. Er lag auf seinem panzerartig harten R�cken und sah, wenn er den Kopf ein wenig hob, seinen gew�lbten, braunen, von bogenf�rmigen Versteifungen geteilten Bauch, auf dessen H�he sich die Bettdecke, zum g�nzlichen Niedergleiten bereit, kaum noch erhalten konnte. Seine vielen, im Vergleich zu seinem sonstigen Umfang kl�glich d�nnen Beine flimmerten ihm hilflos vor den Augen.
�Was ist mit mir geschehen?�, dachte er. Es war kein Traum. Sein Zimmer, ein richtiges, nur etwas zu kleines Menschenzimmer, lag ruhig zwischen den vier wohlbekannten W�nden. �ber dem Tisch, auf dem eine auseinandergepackte Musterkollektion von Tuchwaren ausgebreitet war - Samsa war Reisender - hing das Bild, das er vor kurzem aus einer illustrierten Zeitschrift ausgeschnitten und in einem h�bschen, vergoldeten Rahmen untergebracht hatte. Es stellte eine Dame dar, die mit einem Pelzhut und einer Pelzboa versehen, aufrecht dasa� und einen schweren Pelzmuff, in dem ihr ganzer Unterarm verschwunden war, dem Beschauer entgegenhob.
Gregors Blick richtete sich dann zum Fenster, und das tr�be Wetter - man h�rte Regentropfen auf das Fensterblech aufschlagen - machte ihn ganz melancholisch. �Wie w�re es, wenn ich noch ein wenig weiterschliefe und alle Narrheiten verg��e�, dachte er, aber das war g�nzlich undurchf�hrbar, denn er war gew�hnt, auf der rechten Seite zu schlafen, konnte sich aber in seinem gegenw�rtigen Zustand nicht in diese Lage bringen. Mit welcher Kraft er sich auch auf die rechte Seite warf, immer wieder schaukelte er in die R�ckenlage zur�ck. Er versuchte es wohl hundertmal, schlo� die Augen, um die zappelnden Beine nicht sehen zu m�ssen, und lie� erst ab, als er in der Seite einen noch nie gef�hlten, leichten, dumpfen Schmerz zu f�hlen begann.
�Ach Gott�, dachte er, �was f�r einen anstrengenden Beruf habe ich gew�hlt! Tag aus, Tag ein auf der Reise. Die gesch�ftlichen Aufregungen sind viel gr��er, als im eigentlichen Gesch�ft zu Hause, und au�erdem ist mir noch diese Plage des Reisens auferlegt, die Sorgen um die Zuganschl�sse, das unregelm��ige, schlechte Essen, ein immer wechselnder, nie andauernder, nie herzlich werdender menschlicher Verkehr. Der Teufel soll das alles holen!� Er f�hlte ein leichtes Jucken oben auf dem Bauch; schob sich auf dem R�cken langsam n�her zum Bettpfosten, um den Kopf besser heben zu k�nnen; fand die juckende Stelle, die mit lauter kleinen wei�en P�nktchen besetzt war, die er nicht zu beurteilen verstand; und wollte mit einem Bein die Stelle betasten, zog es aber gleich zur�ck, denn bei der Ber�hrung umwehten ihn K�lteschauer.
Er glitt wieder in seine fr�here Lage zur�ck. �Dies fr�hzeitige Aufstehen�, dachte er, �macht einen ganz bl�dsinnig. Der Mensch mu� seinen Schlaf haben. Andere Reisende leben wie Haremsfrauen. Wenn ich zum Beispiel im Laufe des Vormittags ins Gasthaus zur�ckgehe, um die erlangten Auftr�ge zu �berschreiben, sitzen diese Herren erst beim Fr�hst�ck. Das sollte ich bei meinem Chef versuchen; ich w�rde auf der Stelle hinausfliegen. Wer wei� �brigens, ob das nicht sehr gut f�r mich w�re. Wenn ich mich nicht wegen meiner Eltern zur�ckhielte, ich h�tte l�ngst gek�ndigt, ich w�re vor den Chef hin getreten und h�tte ihm meine Meinung von Grund des Herzens aus gesagt. Vom Pult h�tte er fallen m�ssen! Es ist auch eine sonderbare Art, sich auf das Pult zu setzen und von der H�he herab mit dem Angestellten zu reden, der �berdies wegen der Schwerh�rigkeit des Chefs ganz nahe herantreten mu�. Nun, die Hoffnung ist noch nicht g�nzlich aufgegeben; habe ich einmal das Geld beisammen, um die Schuld der Eltern an ihn abzuzahlen - es d�rfte noch f�nf bis sechs Jahre dauern - , mache ich die Sache unbedingt. Dann wird der gro�e Schnitt gemacht. Vorl�ufig allerdings mu� ich aufstehen, denn mein Zug f�hrt um f�nf.�
Und er sah zur Weckuhr hin�ber, die auf dem Kasten tickte. �Himmlischer Vater!�, dachte er. Es war halb sieben Uhr, und die Zeiger gingen ruhig vorw�rts, es war sogar halb vor�ber, es n�herte sich schon dreiviertel. Sollte der Wecker nicht gel�utet haben? Man sah vom Bett aus, da� er auf vier Uhr richtig eingestellt war; gewi� hatte er auch gel�utet. Ja, aber war es m�glich, dieses m�belersch�tternde L�uten ruhig zu verschlafen? Nun, ruhig hatte er ja nicht geschlafen, aber wahrscheinlich desto fester. Was aber sollte er jetzt tun? Der n�chste Zug ging um sieben Uhr; um den einzuholen, h�tte er sich unsinnig beeilen m�ssen, und die Kollektion war noch nicht eingepackt, und er selbst f�hlte sich durchaus nicht besonders frisch und beweglich. Und selbst wenn er den Zug einholte, ein Donnerwetter des Chefs war nicht zu vermeiden, denn der Gesch�ftsdiener hatte beim F�nfuhrzug gewartet und die Meldung von seiner Vers�umnis l�ngst erstattet. Es war eine Kreatur des Chefs, ohne R�ckgrat und Verstand. Wie nun, wenn er sich krank meldete? Das w�re aber �u�erst peinlich und verd�chtig, denn Gregor war w�hrend seines f�nfj�hrigen Dienstes noch nicht einmal krank gewesen. Gewi� w�rde der Chef mit dem Krankenkassenarzt kommen, w�rde den Eltern wegen des faulen Sohnes Vorw�rfe machen und alle Einw�nde durch den Hinweis auf den Krankenkassenarzt abschneiden, f�r den es ja �berhaupt nur ganz gesunde, aber arbeitsscheue Menschen gibt. Und h�tte er �brigens in diesem Falle so ganz unrecht? Gregor f�hlte sich tats�chlich, abgesehen von einer nach dem langen Schlaf wirklich �berfl�ssigen Schl�frigkeit, ganz wohl und hatte sogar einen besonders kr�ftigen Hunger.
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_latin1_crlf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_latin1_crlf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_latin1_crlf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,11 @@
+Als Gregor Samsa eines Morgens aus unruhigen Tr�umen erwachte, fand er sich in seinem Bett zu einem ungeheueren Ungeziefer verwandelt. Er lag auf seinem panzerartig harten R�cken und sah, wenn er den Kopf ein wenig hob, seinen gew�lbten, braunen, von bogenf�rmigen Versteifungen geteilten Bauch, auf dessen H�he sich die Bettdecke, zum g�nzlichen Niedergleiten bereit, kaum noch erhalten konnte. Seine vielen, im Vergleich zu seinem sonstigen Umfang kl�glich d�nnen Beine flimmerten ihm hilflos vor den Augen.
+
+�Was ist mit mir geschehen?�, dachte er. Es war kein Traum. Sein Zimmer, ein richtiges, nur etwas zu kleines Menschenzimmer, lag ruhig zwischen den vier wohlbekannten W�nden. �ber dem Tisch, auf dem eine auseinandergepackte Musterkollektion von Tuchwaren ausgebreitet war - Samsa war Reisender - hing das Bild, das er vor kurzem aus einer illustrierten Zeitschrift ausgeschnitten und in einem h�bschen, vergoldeten Rahmen untergebracht hatte. Es stellte eine Dame dar, die mit einem Pelzhut und einer Pelzboa versehen, aufrecht dasa� und einen schweren Pelzmuff, in dem ihr ganzer Unterarm verschwunden war, dem Beschauer entgegenhob.
+
+Gregors Blick richtete sich dann zum Fenster, und das tr�be Wetter - man h�rte Regentropfen auf das Fensterblech aufschlagen - machte ihn ganz melancholisch. �Wie w�re es, wenn ich noch ein wenig weiterschliefe und alle Narrheiten verg��e�, dachte er, aber das war g�nzlich undurchf�hrbar, denn er war gew�hnt, auf der rechten Seite zu schlafen, konnte sich aber in seinem gegenw�rtigen Zustand nicht in diese Lage bringen. Mit welcher Kraft er sich auch auf die rechte Seite warf, immer wieder schaukelte er in die R�ckenlage zur�ck. Er versuchte es wohl hundertmal, schlo� die Augen, um die zappelnden Beine nicht sehen zu m�ssen, und lie� erst ab, als er in der Seite einen noch nie gef�hlten, leichten, dumpfen Schmerz zu f�hlen begann.
+
+�Ach Gott�, dachte er, �was f�r einen anstrengenden Beruf habe ich gew�hlt! Tag aus, Tag ein auf der Reise. Die gesch�ftlichen Aufregungen sind viel gr��er, als im eigentlichen Gesch�ft zu Hause, und au�erdem ist mir noch diese Plage des Reisens auferlegt, die Sorgen um die Zuganschl�sse, das unregelm��ige, schlechte Essen, ein immer wechselnder, nie andauernder, nie herzlich werdender menschlicher Verkehr. Der Teufel soll das alles holen!� Er f�hlte ein leichtes Jucken oben auf dem Bauch; schob sich auf dem R�cken langsam n�her zum Bettpfosten, um den Kopf besser heben zu k�nnen; fand die juckende Stelle, die mit lauter kleinen wei�en P�nktchen besetzt war, die er nicht zu beurteilen verstand; und wollte mit einem Bein die Stelle betasten, zog es aber gleich zur�ck, denn bei der Ber�hrung umwehten ihn K�lteschauer.
+
+Er glitt wieder in seine fr�here Lage zur�ck. �Dies fr�hzeitige Aufstehen�, dachte er, �macht einen ganz bl�dsinnig. Der Mensch mu� seinen Schlaf haben. Andere Reisende leben wie Haremsfrauen. Wenn ich zum Beispiel im Laufe des Vormittags ins Gasthaus zur�ckgehe, um die erlangten Auftr�ge zu �berschreiben, sitzen diese Herren erst beim Fr�hst�ck. Das sollte ich bei meinem Chef versuchen; ich w�rde auf der Stelle hinausfliegen. Wer wei� �brigens, ob das nicht sehr gut f�r mich w�re. Wenn ich mich nicht wegen meiner Eltern zur�ckhielte, ich h�tte l�ngst gek�ndigt, ich w�re vor den Chef hin getreten und h�tte ihm meine Meinung von Grund des Herzens aus gesagt. Vom Pult h�tte er fallen m�ssen! Es ist auch eine sonderbare Art, sich auf das Pult zu setzen und von der H�he herab mit dem Angestellten zu reden, der �berdies wegen der Schwerh�rigkeit des Chefs ganz nahe herantreten mu�. Nun, die Hoffnung ist noch nicht g�nzlich aufgegeben; habe ich einmal das Geld beisammen, um die Schuld der Eltern an ihn abzuzahlen - es d�rfte noch f�nf bis sechs Jahre dauern - , mache ich die Sache unbedingt. Dann wird der gro�e Schnitt gemacht. Vorl�ufig allerdings mu� ich aufstehen, denn mein Zug f�hrt um f�nf.�
+
+Und er sah zur Weckuhr hin�ber, die auf dem Kasten tickte. �Himmlischer Vater!�, dachte er. Es war halb sieben Uhr, und die Zeiger gingen ruhig vorw�rts, es war sogar halb vor�ber, es n�herte sich schon dreiviertel. Sollte der Wecker nicht gel�utet haben? Man sah vom Bett aus, da� er auf vier Uhr richtig eingestellt war; gewi� hatte er auch gel�utet. Ja, aber war es m�glich, dieses m�belersch�tternde L�uten ruhig zu verschlafen? Nun, ruhig hatte er ja nicht geschlafen, aber wahrscheinlich desto fester. Was aber sollte er jetzt tun? Der n�chste Zug ging um sieben Uhr; um den einzuholen, h�tte er sich unsinnig beeilen m�ssen, und die Kollektion war noch nicht eingepackt, und er selbst f�hlte sich durchaus nicht besonders frisch und beweglich. Und selbst wenn er den Zug einholte, ein Donnerwetter des Chefs war nicht zu vermeiden, denn der Gesch�ftsdiener hatte beim F�nfuhrzug gewartet und die Meldung von seiner Vers�umnis l�ngst erstattet. Es war eine Kreatur des Chefs, ohne R�ckgrat und Verstand. Wie nun, wenn er sich krank meldete? Das w�re aber �u�erst peinlich und verd�chtig, denn Gregor war w�hrend seines f�nfj�hrigen Dienstes noch nicht einmal krank gewesen. Gewi� w�rde der Chef mit dem Krankenkassenarzt kommen, w�rde den Eltern wegen des faulen Sohnes Vorw�rfe machen und alle Einw�nde durch den Hinweis auf den Krankenkassenarzt abschneiden, f�r den es ja �berhaupt nur ganz gesunde, aber arbeitsscheue Menschen gibt. Und h�tte er �brigens in diesem Falle so ganz unrecht? Gregor f�hlte sich tats�chlich, abgesehen von einer nach dem langen Schlaf wirklich �berfl�ssigen Schl�frigkeit, ganz wohl und hatte sogar einen besonders kr�ftigen Hunger.
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_latin1_lf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_latin1_lf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_latin1_lf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,11 @@
+Als Gregor Samsa eines Morgens aus unruhigen Tr�umen erwachte, fand er sich in seinem Bett zu einem ungeheueren Ungeziefer verwandelt. Er lag auf seinem panzerartig harten R�cken und sah, wenn er den Kopf ein wenig hob, seinen gew�lbten, braunen, von bogenf�rmigen Versteifungen geteilten Bauch, auf dessen H�he sich die Bettdecke, zum g�nzlichen Niedergleiten bereit, kaum noch erhalten konnte. Seine vielen, im Vergleich zu seinem sonstigen Umfang kl�glich d�nnen Beine flimmerten ihm hilflos vor den Augen.
+
+�Was ist mit mir geschehen?�, dachte er. Es war kein Traum. Sein Zimmer, ein richtiges, nur etwas zu kleines Menschenzimmer, lag ruhig zwischen den vier wohlbekannten W�nden. �ber dem Tisch, auf dem eine auseinandergepackte Musterkollektion von Tuchwaren ausgebreitet war - Samsa war Reisender - hing das Bild, das er vor kurzem aus einer illustrierten Zeitschrift ausgeschnitten und in einem h�bschen, vergoldeten Rahmen untergebracht hatte. Es stellte eine Dame dar, die mit einem Pelzhut und einer Pelzboa versehen, aufrecht dasa� und einen schweren Pelzmuff, in dem ihr ganzer Unterarm verschwunden war, dem Beschauer entgegenhob.
+
+Gregors Blick richtete sich dann zum Fenster, und das tr�be Wetter - man h�rte Regentropfen auf das Fensterblech aufschlagen - machte ihn ganz melancholisch. �Wie w�re es, wenn ich noch ein wenig weiterschliefe und alle Narrheiten verg��e�, dachte er, aber das war g�nzlich undurchf�hrbar, denn er war gew�hnt, auf der rechten Seite zu schlafen, konnte sich aber in seinem gegenw�rtigen Zustand nicht in diese Lage bringen. Mit welcher Kraft er sich auch auf die rechte Seite warf, immer wieder schaukelte er in die R�ckenlage zur�ck. Er versuchte es wohl hundertmal, schlo� die Augen, um die zappelnden Beine nicht sehen zu m�ssen, und lie� erst ab, als er in der Seite einen noch nie gef�hlten, leichten, dumpfen Schmerz zu f�hlen begann.
+
+�Ach Gott�, dachte er, �was f�r einen anstrengenden Beruf habe ich gew�hlt! Tag aus, Tag ein auf der Reise. Die gesch�ftlichen Aufregungen sind viel gr��er, als im eigentlichen Gesch�ft zu Hause, und au�erdem ist mir noch diese Plage des Reisens auferlegt, die Sorgen um die Zuganschl�sse, das unregelm��ige, schlechte Essen, ein immer wechselnder, nie andauernder, nie herzlich werdender menschlicher Verkehr. Der Teufel soll das alles holen!� Er f�hlte ein leichtes Jucken oben auf dem Bauch; schob sich auf dem R�cken langsam n�her zum Bettpfosten, um den Kopf besser heben zu k�nnen; fand die juckende Stelle, die mit lauter kleinen wei�en P�nktchen besetzt war, die er nicht zu beurteilen verstand; und wollte mit einem Bein die Stelle betasten, zog es aber gleich zur�ck, denn bei der Ber�hrung umwehten ihn K�lteschauer.
+
+Er glitt wieder in seine fr�here Lage zur�ck. �Dies fr�hzeitige Aufstehen�, dachte er, �macht einen ganz bl�dsinnig. Der Mensch mu� seinen Schlaf haben. Andere Reisende leben wie Haremsfrauen. Wenn ich zum Beispiel im Laufe des Vormittags ins Gasthaus zur�ckgehe, um die erlangten Auftr�ge zu �berschreiben, sitzen diese Herren erst beim Fr�hst�ck. Das sollte ich bei meinem Chef versuchen; ich w�rde auf der Stelle hinausfliegen. Wer wei� �brigens, ob das nicht sehr gut f�r mich w�re. Wenn ich mich nicht wegen meiner Eltern zur�ckhielte, ich h�tte l�ngst gek�ndigt, ich w�re vor den Chef hin getreten und h�tte ihm meine Meinung von Grund des Herzens aus gesagt. Vom Pult h�tte er fallen m�ssen! Es ist auch eine sonderbare Art, sich auf das Pult zu setzen und von der H�he herab mit dem Angestellten zu reden, der �berdies wegen der Schwerh�rigkeit des Chefs ganz nahe herantreten mu�. Nun, die Hoffnung ist noch nicht g�nzlich aufgegeben; habe ich einmal das Geld beisammen, um die Schuld der Eltern an ihn abzuzahlen - es d�rfte noch f�nf bis sechs Jahre dauern - , mache ich die Sache unbedingt. Dann wird der gro�e Schnitt gemacht. Vorl�ufig allerdings mu� ich aufstehen, denn mein Zug f�hrt um f�nf.�
+
+Und er sah zur Weckuhr hin�ber, die auf dem Kasten tickte. �Himmlischer Vater!�, dachte er. Es war halb sieben Uhr, und die Zeiger gingen ruhig vorw�rts, es war sogar halb vor�ber, es n�herte sich schon dreiviertel. Sollte der Wecker nicht gel�utet haben? Man sah vom Bett aus, da� er auf vier Uhr richtig eingestellt war; gewi� hatte er auch gel�utet. Ja, aber war es m�glich, dieses m�belersch�tternde L�uten ruhig zu verschlafen? Nun, ruhig hatte er ja nicht geschlafen, aber wahrscheinlich desto fester. Was aber sollte er jetzt tun? Der n�chste Zug ging um sieben Uhr; um den einzuholen, h�tte er sich unsinnig beeilen m�ssen, und die Kollektion war noch nicht eingepackt, und er selbst f�hlte sich durchaus nicht besonders frisch und beweglich. Und selbst wenn er den Zug einholte, ein Donnerwetter des Chefs war nicht zu vermeiden, denn der Gesch�ftsdiener hatte beim F�nfuhrzug gewartet und die Meldung von seiner Vers�umnis l�ngst erstattet. Es war eine Kreatur des Chefs, ohne R�ckgrat und Verstand. Wie nun, wenn er sich krank meldete? Das w�re aber �u�erst peinlich und verd�chtig, denn Gregor war w�hrend seines f�nfj�hrigen Dienstes noch nicht einmal krank gewesen. Gewi� w�rde der Chef mit dem Krankenkassenarzt kommen, w�rde den Eltern wegen des faulen Sohnes Vorw�rfe machen und alle Einw�nde durch den Hinweis auf den Krankenkassenarzt abschneiden, f�r den es ja �berhaupt nur ganz gesunde, aber arbeitsscheue Menschen gibt. Und h�tte er �brigens in diesem Falle so ganz unrecht? Gregor f�hlte sich tats�chlich, abgesehen von einer nach dem langen Schlaf wirklich �berfl�ssigen Schl�frigkeit, ganz wohl und hatte sogar einen besonders kr�ftigen Hunger.
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_utf8_cr.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_utf8_cr.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_utf8_cr.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1 @@
+Als Gregor Samsa eines Morgens aus unruhigen Träumen erwachte, fand er sich in seinem Bett zu einem ungeheueren Ungeziefer verwandelt. Er lag auf seinem panzerartig harten Rücken und sah, wenn er den Kopf ein wenig hob, seinen gewölbten, braunen, von bogenförmigen Versteifungen geteilten Bauch, auf dessen Höhe sich die Bettdecke, zum gänzlichen Niedergleiten bereit, kaum noch erhalten konnte. Seine vielen, im Vergleich zu seinem sonstigen Umfang kläglich dünnen Beine flimmerten ihm hilflos vor den Augen.
»Was ist mit mir geschehen?«, dachte er. Es war kein Traum. Sein Zimmer, ein richtiges, nur etwas zu kleines Menschenzimmer, lag ruhig zwischen den vier wohlbekannten Wänden. Über dem Tisch, auf dem eine auseinandergepackte Musterkollektion von Tuchwaren ausgebreitet war - Samsa war Reisender - hing das Bild, das er vor kurzem aus einer illustrierten Zeitschrift ausgeschnitten und in einem hübschen, vergoldeten Rahmen untergebracht hatte. Es stellte eine Dame dar, die mit einem Pelzhut und einer Pelzboa versehen, aufrecht dasaß und einen schweren Pelzmuff, in dem ihr ganzer Unterarm verschwunden war, dem Beschauer entgegenhob.
Gregors Blick richtete sich dann zum Fenster, und das trübe Wetter - man hörte Regentropfen auf das Fensterblech aufschlagen - machte ihn ganz melancholisch. »Wie wäre es, wenn ich noch ein wenig weiterschliefe und alle Narrheiten vergäße«, dachte er, aber das war gänzlich undurchführbar, denn er war gewöhnt, auf der rechten Seite zu schlafen, konnte sich aber in seinem gegenwärtigen Zustand nicht in diese Lage bringen. Mit welcher Kraft er sich auch auf die rechte Seite warf, immer wieder schaukelte er in die Rückenlage zurück. Er versuchte es wohl hundertmal, schloß die Augen, um die zappelnden Beine nicht sehen zu müssen, und ließ erst ab, als er in der Seite einen noch nie gefühlten, leichten, dumpfen Schmerz zu fühlen begann.
»Ach Gott«, dachte er, »was für einen anstrengenden Beruf habe ich gewählt! Tag aus, Tag ein auf der Reise. Die geschäftlichen Aufregungen sind viel größer, als im eigentlichen Geschäft zu Hause, und außerdem ist mir noch diese Plage des Reisens auferlegt, die Sorgen um die Zuganschlüsse, das unregelmäßige, schlechte Essen, ein immer wechselnder, nie andauernder, nie herzlich werdender menschlicher Verkehr. Der Teufel soll das alles holen!« Er fühlte ein leichtes Jucken oben auf dem Bauch; schob sich auf dem Rücken langsam näher zum Bettpfosten, um den Kopf besser heben zu können; fand die juckende Stelle, die mit lauter kleinen weißen Pünktchen besetzt war, die er nicht zu beurteilen verstand; und wollte mit einem Bein die Stelle betasten, zog es aber gleich zurück, denn bei der Berührung umwehten ihn Kälteschauer.
Er glitt wieder in seine frühere Lage zurück. »Dies frühzeitige Aufstehen«, dachte er, »macht einen ganz blödsinnig. Der Mensch muß seinen Schlaf haben. Andere Reisende leben wie Haremsfrauen. Wenn ich zum Beispiel im Laufe des Vormittags ins Gasthaus zurückgehe, um die erlangten Aufträge zu überschreiben, sitzen diese Herren erst beim Frühstück. Das sollte ich bei meinem Chef versuchen; ich würde auf der Stelle hinausfliegen. Wer weiß übrigens, ob das nicht sehr gut für mich wäre. Wenn ich mich nicht wegen meiner Eltern zurückhielte, ich hätte längst gekündigt, ich wäre vor den Chef hin getreten und hätte ihm meine Meinung von Grund des Herzens aus gesagt. Vom Pult hätte er fallen müssen! Es ist auch eine sonderbare Art, sich auf das Pult zu setzen und von der Höhe herab mit dem Angestellten zu reden, der überdies wegen der Schwerhörigkeit des Chefs ganz nahe herantreten muß. Nun, die Hoffnung ist noch nicht gänzlich aufgegeben; habe ich einmal das Geld beisammen, um die Schuld der Eltern an ihn abzuzahlen - es dürfte noch fünf bis sechs Jahre dauern - , mache ich die Sache unbedingt. Dann wird der große Schnitt gemacht. Vorläufig allerdings muß ich aufstehen, denn mein Zug fährt um fünf.«
Und er sah zur Weckuhr hinüber, die auf dem Kasten tickte. »Himmlischer Vater!«, dachte er. Es war halb sieben Uhr, und die Zeiger gingen ruhig vorwärts, es war sogar halb vorüber, es näherte sich schon dreiviertel. Sollte der Wecker nicht geläutet haben? Man sah vom Bett aus, daß er auf vier Uhr richtig eingestellt war; gewiß hatte er auch geläutet. Ja, aber war es möglich, dieses möbelerschütternde Läuten ruhig zu verschlafen? Nun, ruhig hatte er ja nicht geschlafen, aber wahrscheinlich desto fester. Was aber sollte er jetzt tun? Der nächste Zug ging um sieben Uhr; um den einzuholen, hätte er sich unsinnig beeilen müssen, und die Kollektion war noch nicht eingepackt, und er selbst fühlte sich durchaus nicht besonders frisch und beweglich. Und selbst wenn er den Zug einholte, ein Donnerwetter des Chefs war nicht zu vermeiden, denn der Geschäftsdiener hatte beim Fünfuhrzug gewartet und die Meldung von seiner Versäumnis längst erstattet. Es war eine Kreatur des Chefs, ohne Rückgrat und Verstand. Wie nun, wenn er sich krank meldete? Das wäre aber äußerst peinlich und verdächtig, denn Gregor war während seines fünfjährigen Dienstes noch nicht einmal krank gewesen. Gewiß würde der Chef mit dem Krankenkassenarzt kommen, würde den Eltern wegen des faulen Sohnes Vorwürfe machen und alle Einwände durch den Hinweis auf den Krankenkassenarzt abschneiden, für den es ja überhaupt nur ganz gesunde, aber arbeitsscheue Menschen gibt. Und hätte er übrigens in diesem Falle so ganz unrecht? Gregor fühlte sich tatsächlich, abgesehen von einer nach dem langen Schlaf wirklich überflüssigen Schläfrigkeit, ganz wohl und hatte sogar einen besonders kräftigen Hunger.
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_utf8_crlf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_utf8_crlf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_utf8_crlf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,11 @@
+Als Gregor Samsa eines Morgens aus unruhigen Träumen erwachte, fand er sich in seinem Bett zu einem ungeheueren Ungeziefer verwandelt. Er lag auf seinem panzerartig harten Rücken und sah, wenn er den Kopf ein wenig hob, seinen gewölbten, braunen, von bogenförmigen Versteifungen geteilten Bauch, auf dessen Höhe sich die Bettdecke, zum gänzlichen Niedergleiten bereit, kaum noch erhalten konnte. Seine vielen, im Vergleich zu seinem sonstigen Umfang kläglich dünnen Beine flimmerten ihm hilflos vor den Augen.
+
+»Was ist mit mir geschehen?«, dachte er. Es war kein Traum. Sein Zimmer, ein richtiges, nur etwas zu kleines Menschenzimmer, lag ruhig zwischen den vier wohlbekannten Wänden. Über dem Tisch, auf dem eine auseinandergepackte Musterkollektion von Tuchwaren ausgebreitet war - Samsa war Reisender - hing das Bild, das er vor kurzem aus einer illustrierten Zeitschrift ausgeschnitten und in einem hübschen, vergoldeten Rahmen untergebracht hatte. Es stellte eine Dame dar, die mit einem Pelzhut und einer Pelzboa versehen, aufrecht dasaß und einen schweren Pelzmuff, in dem ihr ganzer Unterarm verschwunden war, dem Beschauer entgegenhob.
+
+Gregors Blick richtete sich dann zum Fenster, und das trübe Wetter - man hörte Regentropfen auf das Fensterblech aufschlagen - machte ihn ganz melancholisch. »Wie wäre es, wenn ich noch ein wenig weiterschliefe und alle Narrheiten vergäße«, dachte er, aber das war gänzlich undurchführbar, denn er war gewöhnt, auf der rechten Seite zu schlafen, konnte sich aber in seinem gegenwärtigen Zustand nicht in diese Lage bringen. Mit welcher Kraft er sich auch auf die rechte Seite warf, immer wieder schaukelte er in die Rückenlage zurück. Er versuchte es wohl hundertmal, schloß die Augen, um die zappelnden Beine nicht sehen zu müssen, und ließ erst ab, als er in der Seite einen noch nie gefühlten, leichten, dumpfen Schmerz zu fühlen begann.
+
+»Ach Gott«, dachte er, »was für einen anstrengenden Beruf habe ich gewählt! Tag aus, Tag ein auf der Reise. Die geschäftlichen Aufregungen sind viel größer, als im eigentlichen Geschäft zu Hause, und außerdem ist mir noch diese Plage des Reisens auferlegt, die Sorgen um die Zuganschlüsse, das unregelmäßige, schlechte Essen, ein immer wechselnder, nie andauernder, nie herzlich werdender menschlicher Verkehr. Der Teufel soll das alles holen!« Er fühlte ein leichtes Jucken oben auf dem Bauch; schob sich auf dem Rücken langsam näher zum Bettpfosten, um den Kopf besser heben zu können; fand die juckende Stelle, die mit lauter kleinen weißen Pünktchen besetzt war, die er nicht zu beurteilen verstand; und wollte mit einem Bein die Stelle betasten, zog es aber gleich zurück, denn bei der Berührung umwehten ihn Kälteschauer.
+
+Er glitt wieder in seine frühere Lage zurück. »Dies frühzeitige Aufstehen«, dachte er, »macht einen ganz blödsinnig. Der Mensch muß seinen Schlaf haben. Andere Reisende leben wie Haremsfrauen. Wenn ich zum Beispiel im Laufe des Vormittags ins Gasthaus zurückgehe, um die erlangten Aufträge zu überschreiben, sitzen diese Herren erst beim Frühstück. Das sollte ich bei meinem Chef versuchen; ich würde auf der Stelle hinausfliegen. Wer weiß übrigens, ob das nicht sehr gut für mich wäre. Wenn ich mich nicht wegen meiner Eltern zurückhielte, ich hätte längst gekündigt, ich wäre vor den Chef hin getreten und hätte ihm meine Meinung von Grund des Herzens aus gesagt. Vom Pult hätte er fallen müssen! Es ist auch eine sonderbare Art, sich auf das Pult zu setzen und von der Höhe herab mit dem Angestellten zu reden, der überdies wegen der Schwerhörigkeit des Chefs ganz nahe herantreten muß. Nun, die Hoffnung ist noch nicht gänzlich aufgegeben; habe ich einmal das Geld beisammen, um die Schuld der Eltern an ihn abzuzahlen - es dürfte noch fünf bis sechs Jahre dauern - , mache ich die Sache unbedingt. Dann wird der große Schnitt gemacht. Vorläufig allerdings muß ich aufstehen, denn mein Zug fährt um fünf.«
+
+Und er sah zur Weckuhr hinüber, die auf dem Kasten tickte. »Himmlischer Vater!«, dachte er. Es war halb sieben Uhr, und die Zeiger gingen ruhig vorwärts, es war sogar halb vorüber, es näherte sich schon dreiviertel. Sollte der Wecker nicht geläutet haben? Man sah vom Bett aus, daß er auf vier Uhr richtig eingestellt war; gewiß hatte er auch geläutet. Ja, aber war es möglich, dieses möbelerschütternde Läuten ruhig zu verschlafen? Nun, ruhig hatte er ja nicht geschlafen, aber wahrscheinlich desto fester. Was aber sollte er jetzt tun? Der nächste Zug ging um sieben Uhr; um den einzuholen, hätte er sich unsinnig beeilen müssen, und die Kollektion war noch nicht eingepackt, und er selbst fühlte sich durchaus nicht besonders frisch und beweglich. Und selbst wenn er den Zug einholte, ein Donnerwetter des Chefs war nicht zu vermeiden, denn der Geschäftsdiener hatte beim Fünfuhrzug gewartet und die Meldung von seiner Versäumnis längst erstattet. Es war eine Kreatur des Chefs, ohne Rückgrat und Verstand. Wie nun, wenn er sich krank meldete? Das wäre aber äußerst peinlich und verdächtig, denn Gregor war während seines fünfjährigen Dienstes noch nicht einmal krank gewesen. Gewiß würde der Chef mit dem Krankenkassenarzt kommen, würde den Eltern wegen des faulen Sohnes Vorwürfe machen und alle Einwände durch den Hinweis auf den Krankenkassenarzt abschneiden, für den es ja überhaupt nur ganz gesunde, aber arbeitsscheue Menschen gibt. Und hätte er übrigens in diesem Falle so ganz unrecht? Gregor fühlte sich tatsächlich, abgesehen von einer nach dem langen Schlaf wirklich überflüssigen Schläfrigkeit, ganz wohl und hatte sogar einen besonders kräftigen Hunger.
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_utf8_lf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_utf8_lf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/kafka_utf8_lf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,11 @@
+Als Gregor Samsa eines Morgens aus unruhigen Träumen erwachte, fand er sich in seinem Bett zu einem ungeheueren Ungeziefer verwandelt. Er lag auf seinem panzerartig harten Rücken und sah, wenn er den Kopf ein wenig hob, seinen gewölbten, braunen, von bogenförmigen Versteifungen geteilten Bauch, auf dessen Höhe sich die Bettdecke, zum gänzlichen Niedergleiten bereit, kaum noch erhalten konnte. Seine vielen, im Vergleich zu seinem sonstigen Umfang kläglich dünnen Beine flimmerten ihm hilflos vor den Augen.
+
+»Was ist mit mir geschehen?«, dachte er. Es war kein Traum. Sein Zimmer, ein richtiges, nur etwas zu kleines Menschenzimmer, lag ruhig zwischen den vier wohlbekannten Wänden. Über dem Tisch, auf dem eine auseinandergepackte Musterkollektion von Tuchwaren ausgebreitet war - Samsa war Reisender - hing das Bild, das er vor kurzem aus einer illustrierten Zeitschrift ausgeschnitten und in einem hübschen, vergoldeten Rahmen untergebracht hatte. Es stellte eine Dame dar, die mit einem Pelzhut und einer Pelzboa versehen, aufrecht dasaß und einen schweren Pelzmuff, in dem ihr ganzer Unterarm verschwunden war, dem Beschauer entgegenhob.
+
+Gregors Blick richtete sich dann zum Fenster, und das trübe Wetter - man hörte Regentropfen auf das Fensterblech aufschlagen - machte ihn ganz melancholisch. »Wie wäre es, wenn ich noch ein wenig weiterschliefe und alle Narrheiten vergäße«, dachte er, aber das war gänzlich undurchführbar, denn er war gewöhnt, auf der rechten Seite zu schlafen, konnte sich aber in seinem gegenwärtigen Zustand nicht in diese Lage bringen. Mit welcher Kraft er sich auch auf die rechte Seite warf, immer wieder schaukelte er in die Rückenlage zurück. Er versuchte es wohl hundertmal, schloß die Augen, um die zappelnden Beine nicht sehen zu müssen, und ließ erst ab, als er in der Seite einen noch nie gefühlten, leichten, dumpfen Schmerz zu fühlen begann.
+
+»Ach Gott«, dachte er, »was für einen anstrengenden Beruf habe ich gewählt! Tag aus, Tag ein auf der Reise. Die geschäftlichen Aufregungen sind viel größer, als im eigentlichen Geschäft zu Hause, und außerdem ist mir noch diese Plage des Reisens auferlegt, die Sorgen um die Zuganschlüsse, das unregelmäßige, schlechte Essen, ein immer wechselnder, nie andauernder, nie herzlich werdender menschlicher Verkehr. Der Teufel soll das alles holen!« Er fühlte ein leichtes Jucken oben auf dem Bauch; schob sich auf dem Rücken langsam näher zum Bettpfosten, um den Kopf besser heben zu können; fand die juckende Stelle, die mit lauter kleinen weißen Pünktchen besetzt war, die er nicht zu beurteilen verstand; und wollte mit einem Bein die Stelle betasten, zog es aber gleich zurück, denn bei der Berührung umwehten ihn Kälteschauer.
+
+Er glitt wieder in seine frühere Lage zurück. »Dies frühzeitige Aufstehen«, dachte er, »macht einen ganz blödsinnig. Der Mensch muß seinen Schlaf haben. Andere Reisende leben wie Haremsfrauen. Wenn ich zum Beispiel im Laufe des Vormittags ins Gasthaus zurückgehe, um die erlangten Aufträge zu überschreiben, sitzen diese Herren erst beim Frühstück. Das sollte ich bei meinem Chef versuchen; ich würde auf der Stelle hinausfliegen. Wer weiß übrigens, ob das nicht sehr gut für mich wäre. Wenn ich mich nicht wegen meiner Eltern zurückhielte, ich hätte längst gekündigt, ich wäre vor den Chef hin getreten und hätte ihm meine Meinung von Grund des Herzens aus gesagt. Vom Pult hätte er fallen müssen! Es ist auch eine sonderbare Art, sich auf das Pult zu setzen und von der Höhe herab mit dem Angestellten zu reden, der überdies wegen der Schwerhörigkeit des Chefs ganz nahe herantreten muß. Nun, die Hoffnung ist noch nicht gänzlich aufgegeben; habe ich einmal das Geld beisammen, um die Schuld der Eltern an ihn abzuzahlen - es dürfte noch fünf bis sechs Jahre dauern - , mache ich die Sache unbedingt. Dann wird der große Schnitt gemacht. Vorläufig allerdings muß ich aufstehen, denn mein Zug fährt um fünf.«
+
+Und er sah zur Weckuhr hinüber, die auf dem Kasten tickte. »Himmlischer Vater!«, dachte er. Es war halb sieben Uhr, und die Zeiger gingen ruhig vorwärts, es war sogar halb vorüber, es näherte sich schon dreiviertel. Sollte der Wecker nicht geläutet haben? Man sah vom Bett aus, daß er auf vier Uhr richtig eingestellt war; gewiß hatte er auch geläutet. Ja, aber war es möglich, dieses möbelerschütternde Läuten ruhig zu verschlafen? Nun, ruhig hatte er ja nicht geschlafen, aber wahrscheinlich desto fester. Was aber sollte er jetzt tun? Der nächste Zug ging um sieben Uhr; um den einzuholen, hätte er sich unsinnig beeilen müssen, und die Kollektion war noch nicht eingepackt, und er selbst fühlte sich durchaus nicht besonders frisch und beweglich. Und selbst wenn er den Zug einholte, ein Donnerwetter des Chefs war nicht zu vermeiden, denn der Geschäftsdiener hatte beim Fünfuhrzug gewartet und die Meldung von seiner Versäumnis längst erstattet. Es war eine Kreatur des Chefs, ohne Rückgrat und Verstand. Wie nun, wenn er sich krank meldete? Das wäre aber äußerst peinlich und verdächtig, denn Gregor war während seines fünfjährigen Dienstes noch nicht einmal krank gewesen. Gewiß würde der Chef mit dem Krankenkassenarzt kommen, würde den Eltern wegen des faulen Sohnes Vorwürfe machen und alle Einwände durch den Hinweis auf den Krankenkassenarzt abschneiden, für den es ja überhaupt nur ganz gesunde, aber arbeitsscheue Menschen gibt. Und hätte er übrigens in diesem Falle so ganz unrecht? Gregor fühlte sich tatsächlich, abgesehen von einer nach dem langen Schlaf wirklich überflüssigen Schläfrigkeit, ganz wohl und hatte sogar einen besonders kräftigen Hunger.
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/packages.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/packages.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/packages.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,33 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CL-USER; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/test/packages.lisp,v 1.4 2007/01/01 23:47:16 edi Exp $
+
+;;; Copyright (c) 2006-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :cl-user)
+
+(defpackage :flexi-streams-test
+ (:use :cl :flexi-streams))
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_koi8r_cr.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_koi8r_cr.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_koi8r_cr.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1 @@
+����������������� ������ �� ������� ������������� ����������� ��
Unicode, ������� ��������� 10-12 ����� 1997 ���� � ������ � ��������.
����������� ������� ������� ���� ��������� �� �������� �����������
��������� � Unicode, ����������� � �������������������, ���������� �
���������� Unicode � ��������� ������������ �������� � �����������
�����������, �������, ������� � ������������ ������������ ��������.
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_koi8r_crlf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_koi8r_crlf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_koi8r_crlf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,6 @@
+����������������� ������ �� ������� ������������� ����������� ��
+Unicode, ������� ��������� 10-12 ����� 1997 ���� � ������ � ��������.
+����������� ������� ������� ���� ��������� �� �������� �����������
+��������� � Unicode, ����������� � �������������������, ���������� �
+���������� Unicode � ��������� ������������ �������� � �����������
+�����������, �������, ������� � ������������ ������������ ��������.
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_koi8r_lf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_koi8r_lf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_koi8r_lf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,6 @@
+����������������� ������ �� ������� ������������� ����������� ��
+Unicode, ������� ��������� 10-12 ����� 1997 ���� � ������ � ��������.
+����������� ������� ������� ���� ��������� �� �������� �����������
+��������� � Unicode, ����������� � �������������������, ���������� �
+���������� Unicode � ��������� ������������ �������� � �����������
+�����������, �������, ������� � ������������ ������������ ��������.
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_utf8_cr.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_utf8_cr.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_utf8_crlf.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_utf8_crlf.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_utf8_lf.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/russian_utf8_lf.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/test.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/test.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/test.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,313 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FLEXI-STREAMS-TEST; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/test/test.lisp,v 1.12 2007/03/09 01:14:30 edi Exp $
+
+;;; Copyright (c) 2006-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :flexi-streams-test)
+
+(defvar *this-file* (load-time-value
+ (or #.*compile-file-pathname* *load-pathname*))
+ "The pathname of the file (`test.lisp') where this variable was
+defined.")
+
+(defvar *tmp-dir*
+ (load-time-value
+ (merge-pathnames "flexi-streams-test/"
+ #+:allegro (system:temporary-directory)
+ #+:lispworks (pathname (or (lw:environment-variable "TEMP")
+ (lw:environment-variable "TMP")
+ #+:win32 "C:/"
+ #-:win32 "/tmp/"))
+ #-(or :allegro :lispworks) #p"/tmp/"))
+ "The pathname of a temporary directory used for testing.")
+
+(defvar *test-files*
+ '(("kafka" (:utf8 :latin1 :cp1252))
+ ("tilton" (:utf8 :ascii))
+ ("hebrew" (:utf8 :latin8))
+ ("russian" (:utf8 :koi8r))
+ ("unicode_demo" (:utf8 :ucs2 :ucs4)))
+ "A list of test files where each entry consists of the name
+prefix and a list of encodings.")
+
+(defvar *test-success-counter* 0
+ "Counts the number of successful tests.")
+
+(defun create-file-variants (file-name symbol)
+ "For a name suffix FILE-NAME and a symbol SYMBOL denoting an
+encoding returns a list of pairs where the car is a full file
+name and the cdr is the corresponding external format. This list
+contains all possible variants w.r.t. to line-end conversion and
+endianness."
+ (let ((args (ecase symbol
+ (:ascii '(:ascii))
+ (:latin1 '(:latin-1))
+ (:latin8 '(:hebrew))
+ (:cp1252 '(:code-page :id 1252))
+ (:koi8r '(:koi8-r))
+ (:utf8 '(:utf-8))
+ (:ucs2 '(:utf-16))
+ (:ucs4 '(:utf-32))))
+ (endianp (member symbol '(:ucs2 :ucs4))))
+ (loop for little-endian in (if endianp '(t nil) '(t))
+ for endian-suffix in (if endianp '("_le" "_be") '(""))
+ nconc (loop for eol-style in '(:lf :cr :crlf)
+ collect (cons (format nil "~A_~(~A~)_~(~A~)~A.txt"
+ file-name symbol eol-style endian-suffix)
+ (apply #'make-external-format
+ (append args `(:eol-style ,eol-style
+ :little-endian ,little-endian))))))))
+
+(defun create-test-combinations (file-name symbols)
+ "For a name suffix FILE-NAME and a list of symbols SYMBOLS
+denoting different encodings of the corresponding file returns a
+list of lists which can be used as arglists for COMPARE-FILES."
+ (let ((file-variants (loop for symbol in symbols
+ nconc (create-file-variants file-name symbol))))
+ (loop for (name-in . external-format-in) in file-variants
+ nconc (loop for (name-out . external-format-out) in file-variants
+ collect (list name-in external-format-in name-out external-format-out)))))
+
+(defun file-equal (file1 file2)
+ "Returns a true value iff FILE1 and FILE2 have the same
+contents \(viewed as binary files)."
+ (with-open-file (stream1 file1 :element-type 'octet)
+ (with-open-file (stream2 file2 :element-type 'octet)
+ (and (= (file-length stream1) (file-length stream2))
+ (loop for byte1 = (read-byte stream1 nil nil)
+ for byte2 = (read-byte stream2 nil nil)
+ while (and byte1 byte2)
+ always (= byte1 byte2))))))
+
+(defun copy-stream (stream-in external-format-in stream-out external-format-out)
+ "Copies the contents of the binary stream STREAM-IN to the
+binary stream STREAM-OUT using flexi streams - STREAM-IN is read
+with the external format EXTERNAL-FORMAT-IN and STREAM-OUT is
+written with EXTERNAL-FORMAT-OUT."
+ (let ((in (make-flexi-stream stream-in :external-format external-format-in))
+ (out (make-flexi-stream stream-out :external-format external-format-out)))
+ (loop for line = (read-line in nil nil)
+ while line
+ do (write-line line out))))
+
+(defun copy-file (path-in external-format-in path-out external-format-out direction-out direction-in)
+ "Copies the contents of the file denoted by the pathname
+PATH-IN to the file denoted by the pathname PATH-OUT using flexi
+streams - STREAM-IN is read with the external format
+EXTERNAL-FORMAT-IN and STREAM-OUT is written with
+EXTERNAL-FORMAT-OUT. The input file is opened with
+the :DIRECTION keyword argument DIRECTION-IN, the output file is
+opened with the :DIRECTION keyword argument DIRECTION-OUT."
+ (with-open-file (in path-in
+ :element-type 'octet
+ :direction direction-in
+ :if-does-not-exist :error
+ :if-exists :overwrite)
+ (with-open-file (out path-out
+ :element-type 'octet
+ :direction direction-out
+ :if-does-not-exist :create
+ :if-exists :supersede)
+ (copy-stream in external-format-in out external-format-out))))
+
+#+:lispworks
+(defun copy-file-lw (path-in external-format-in path-out external-format-out direction-out direction-in)
+ "Same as COPY-FILE, but uses character streams instead of
+binary streams. Only used to test LispWorks-specific behaviour."
+ (with-open-file (in path-in
+ :external-format '(:latin-1 :eol-style :lf)
+ :direction direction-in
+ :if-does-not-exist :error
+ :if-exists :overwrite)
+ (with-open-file (out path-out
+ :external-format '(:latin-1 :eol-style :lf)
+ :direction direction-out
+ :direction :output
+ :if-does-not-exist :create
+ :if-exists :supersede)
+ (copy-stream in external-format-in out external-format-out))))
+
+(defun compare-files (path-in external-format-in path-out external-format-out)
+ "Copies the contents of the file (in the `test') denoted by the
+relative pathname PATH-IN to the file (in a temporary directory)
+denoted by the relative pathname PATH-OUT using flexi streams -
+STREAM-IN is read with the external format EXTERNAL-FORMAT-IN and
+STREAM-OUT is written with EXTERNAL-FORMAT-OUT. The resulting
+file is compared with an existing file in the `test' directory to
+check if the outcome is as expected. Uses various variants of
+the :DIRECTION keyword when opening the files."
+ (let ((full-path-in (merge-pathnames path-in *this-file*))
+ (full-path-out (ensure-directories-exist
+ (merge-pathnames path-out *tmp-dir*)))
+ (full-path-orig (merge-pathnames path-out *this-file*)))
+ (dolist (direction-out '(:output :io))
+ (dolist (direction-in '(:input :io))
+ (format *error-output* "Test ~S ~S [~A]~% --> ~S [~A].~%" path-in
+ (flex::normalize-external-format external-format-in) direction-in
+ (flex::normalize-external-format external-format-out) direction-out)
+ (copy-file full-path-in external-format-in
+ full-path-out external-format-out
+ direction-out direction-in)
+ (cond ((file-equal full-path-out full-path-orig)
+ (incf *test-success-counter*))
+ (t (format *error-output* " Test failed!!!~%")))
+ (terpri *error-output*)
+ #+:lispworks
+ (format *error-output* "LW-Test ~S ~S [~A]~% --> ~S [~A].~%" path-in
+ (flex::normalize-external-format external-format-in) direction-in
+ (flex::normalize-external-format external-format-out) direction-out)
+ #+:lispworks
+ (copy-file full-path-in external-format-in
+ full-path-out external-format-out
+ direction-out direction-in)
+ #+:lispworks
+ (cond ((file-equal full-path-out full-path-orig)
+ (incf *test-success-counter*))
+ (t (format *error-output* " Test failed!!!~%")))
+ (terpri *error-output*)))))
+
+(defmacro with-test ((test-description) &body body)
+ "Defines a test. Two utilities are available inside of the body of
+the maco: The function FAIL, and the macro CHECK. FAIL, the lowest
+level utility, marks the test defined by WITH-TEST as faided. CHECK
+checks whether its argument is true, otherwise it calls FAIL. If
+during evaluation of the specified expression any condition is
+signaled, this is also considered a failure.
+
+WITH-TEST prints reports while the tests run. It also increments
+*TEST-SUCCESS-COUNT* if a test completes successfully."
+ (flex::with-unique-names (successp)
+ `(let ((,successp t))
+ (flet ((fail (format-str &rest format-args)
+ (setf ,successp nil)
+ (apply #'format *error-output* format-str format-args)))
+ (macrolet ((check (expression)
+ `(handler-case
+ (unless ,expression
+ (fail "Expression ~S failed.~%" ',expression))
+ (condition (c)
+ (fail "Expression ~S failed signaling condition of type ~A: ~A.~%"
+ ',expression (type-of c) c)))))
+ (format *error-output* "Test ~S~%" ,test-description)
+ ,@body
+ (if ,successp
+ (incf *test-success-counter*)
+ (format *error-output* " Test failed!!!~%"))
+ (terpri *error-output*)
+ (terpri *error-output*))
+ ,successp))))
+
+(defmacro using-values ((&rest values) &body body)
+ "Executes BODY and feeds an element from VALUES to the USE-VALUE
+restart each time a FLEXI-STREAM-ENCODING-ERROR is signaled. Signals
+an error when there are more or less FLEXI-STREAM-ENCODING-ERRORs than
+there are elements in VALUES."
+ (flex::with-unique-names (value-stack condition-counter)
+ `(let ((,value-stack ',values)
+ (,condition-counter 0))
+ (handler-bind ((flexi-stream-encoding-error
+ #'(lambda (c)
+ (declare (ignore c))
+ (unless ,value-stack
+ (error "Too many FLEXI-STREAM-ENCODING-ERRORs signaled, expected only ~A."
+ ,(length values)))
+ (incf ,condition-counter)
+ (use-value (pop ,value-stack)))))
+ (prog1 (progn ,@body)
+ (when ,value-stack
+ (error "~A FLEXI-STREAM-ENCODING-ERRORs signaled, but ~A were expected."
+ ,condition-counter ,(length values))))))))
+
+(defun read-flexi-line (sequence external-format)
+ "Creates and returns a string from the octet sequence SEQUENCE using
+the external format EXTERNAL-FORMAT."
+ (with-input-from-sequence (in sequence)
+ (setq in (make-flexi-stream in :external-format external-format))
+ (read-line in)))
+
+(defun encoding-error-handling-test()
+ (with-test ("Handling of encoding errors")
+ (let ((*substitution-char* #\?))
+ ;; :ASCII doesn't have characters with char codes > 127
+ (check (string= "a??" (read-flexi-line `(,(char-code #\a) 128 200) :ascii)))
+ ;; :WINDOWS-1253 doesn't have a characters with codes 170 and 210
+ (check (string= "a??" (read-flexi-line `(,(char-code #\a) 170 210) :windows-1253)))
+ ;; not a valid UTF-8 sequence
+ (check (string= "??" (read-flexi-line `(#xe4 #xf6 #xfc) :utf8)))
+ ;; UTF-8 can't start neither with #b11111110 nor with #b11111111
+ (check (string= "??" (read-flexi-line `(#b11111110 #b11111111) :utf8))))
+ (let ((*substitution-char* nil))
+ ;; :ASCII doesn't have characters with char codes > 127
+ (check (string= "abc" (using-values (#\b #\c)
+ (read-flexi-line `(,(char-code #\a) 128 200) :ascii))))
+ ;; :WINDOWS-1253 encoding doesn't have a characters with codes 170 and 210
+ (check (string= "axy" (using-values (#\x #\y)
+ (read-flexi-line `(,(char-code #\a) 170 210) :windows-1253))))
+ ;; not a valid UTF-8 sequence
+ (check (string= "QW" (using-values (#\Q #\W) (read-flexi-line `(#xe4 #xf6 #xfc) :utf8))))
+ ;; UTF-8 can't start neither with #b11111110 nor with #b11111111
+ (check (string= "QW" (using-values (#\Q #\W) (read-flexi-line `(#b11111110 #b11111111) :utf8))))
+ ;; only one byte
+ (check (string= "E" (using-values (#\E) (read-flexi-line `(#x01) :utf-16le))))
+ ;; two bytes, but value of resulting word suggests that another word follows
+ (check (string= "R" (using-values (#\R) (read-flexi-line `(#x01 #xd8) :utf-16le))))
+ ;; the second word must fit into the [#xdc00; #xdfff] interval, but it is #xdbff
+ (check (string= "T" (using-values (#\T) (read-flexi-line `(#x01 #xd8 #xff #xdb) :utf-16le))))
+ ;; the same as for little endian above, but using inverse order of bytes in words
+ (check (string= "E" (using-values (#\E) (read-flexi-line `(#x01) :utf-16be))))
+ (check (string= "R" (using-values (#\R) (read-flexi-line `(#xd8 #x01) :utf-16be))))
+ (check (string= "T" (using-values (#\T) (read-flexi-line `(#xd8 #x01 #xdb #xff) :utf-16be))))
+ ;; the only case when error is signaled for UTF-32 is at end of file
+ ;; in the middle of 4-byte sequence, both for big and little endian
+ (check (string= "Y" (using-values (#\Y) (read-flexi-line `(#x01) :utf-32le))))
+ (check (string= "Y" (using-values (#\Y) (read-flexi-line `(#x01 #x01) :utf-32le))))
+ (check (string= "Y" (using-values (#\Y) (read-flexi-line `(#x01 #x01 #x01) :utf-32le))))
+ (check (string= "aY" (using-values (#\Y)
+ (read-flexi-line `(,(char-code #\a) #x00 #x00 #x00 #x01) :utf-32le))))
+ (check (string= "Y" (using-values (#\Y) (read-flexi-line `(#x01) :utf-32be))))
+ (check (string= "Y" (using-values (#\Y) (read-flexi-line `(#x01 #x01) :utf-32be))))
+ (check (string= "Y" (using-values (#\Y) (read-flexi-line `(#x01 #x01 #x01) :utf-32be))))
+ (check (string= "aY" (using-values (#\Y)
+ (read-flexi-line `(#x00 #x00 #x00 ,(char-code #\a) #x01) :utf-32be)))))))
+
+(defun run-tests ()
+ "Applies COMPARE-FILES to all test scenarios created with
+CREATE-TEST-COMBINATIONS, runs test for handling of encoding errors,
+and shows simple statistics at the end."
+ (let* ((*test-success-counter* 0)
+ (args-list (loop for (file-name symbols) in *test-files*
+ nconc (create-test-combinations file-name symbols)))
+ (no-tests (* 4 (length args-list))))
+ #+:lispworks
+ (setq no-tests (* 2 no-tests))
+ (dolist (args args-list)
+ (apply #'compare-files args))
+ (incf no-tests)
+ (encoding-error-handling-test)
+ (format *error-output* "~%~%~:[~A of ~A tests failed..~;~*All ~A tests passed~].~%"
+ (= no-tests *test-success-counter*) (- no-tests *test-success-counter*) no-tests)))
+
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_ascii_cr.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_ascii_cr.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_ascii_cr.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1 @@
+Programmers who lock onto a design decision and cling to it in the face of
contradictory new information -- well, that's almost everyone in my
experience, so I better not say what I think of them or people will start
saying bad things about me on c.l.l.
-- Ken Tilton
%
This reminds me of the NYC cabby who accepted a fare to Chicago. When
they got there and could not find the friend who was supposed to pay the
fare he just laughed and said he should have known.
-- Ken Tilton
%
>> Actually, I believe that Aikido, Jazz and Lisp are different appearances
>> of the same thing.
Yes, the Tao. /Everything/ is a different appearance of the tao.
-- Ken Tilton
"Ken, I went to the library and read up on Buddhism, and believe me, you
are no Buddhist."
-- Kenny's mom
%
That absolutely terrifies the herd-following, lockstep-marching,
mainstream-saluting cowards that obediently dash out or online to
scoop up books on The Latest Thing. They learn and use atrocities like
Java, C++, XML, and even Python for the security it gives them and
then sit there slaving away miserably, tediously, joylously paying off
mortgages and supporting ungrateful teenagers who despise them, only
to look out the double-sealed thermo-pane windows of their
central-heated, sound-proofed, dead-bolted, suffocating little nests
into the howling gale thinking "what do they know that I do not know?"
when they see us under a lean-to hunched over our laptops to shield
them from the rain laughing our asses off as we write great code
between bong hits.... what was the question?
-- Ken Tilton
%
Shut up! (That last phrase has four or more syllables if pronounced as
intended.)
-- Ken Tilton
%
Nonsense. You'll be using it for the GUI, not protein-folding.
-- Ken Tilton
(responding to a comment that LTK was slow because it
was based on TK)
%
Continuations certainly are clever, but if we learned anything from the
rejection of the cover art for "Smell the Glove", it is that "there is a
fine line between stupid... and clever".
-- Ken Tilton
%
Ah, there's no place like academia for dispassionate, intellectually
honest discussion of new ideas on their merits. Thank god for tenure
giving your bold antagonist the protection they needed to shout down
your iconoclastic..... hang on...
-- Ken Tilton
%
Whoever objected must be in my killfile, ...
-- Ken Tilton
%
From memory (but I think I have it right):
"But Jesus said, Suffer captured variables, and forbid them not, to come
unto thine macro bodies: for of such is are DSLs made."
-- Ken Tilton
Can I get an Amen?
%
Awareness of defect is the first step to recovery.
-- Ken Tilton
%
You made a bad analogy (there are no good ones, but you found a new
low) ...
-- Ken Tilton
%
Yes, it is true that Kent Pitman was raised by a closet full of Lisp
Machines, but the exception only proves the rule.
-- Ken Tilton
(in a postscript after positing that computer
languages are not learned in infancy)
%
I suggest you try bartender's school to support yourself, start
programming for fun again.
-- Ken Tilton
(responding to a comment that 98% of anything to do
with computers was not interesting code)
%
You could add four lanes to my carpal tunnel and I still could not
write all the code I am dying to write.
-- Ken Tilton
%
Neutrality? I want to bury other languages, not have a gateway to them.
-- Ken Tilton
%
Ken: "Cute puppy. Did you get it for companionship or to pick up chicks?"
Simon: "Hunh? My puppy /always/ gives me companionship."
-- Ken Tilton
(on how he was understood by a native english speaker)
%
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_ascii_crlf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_ascii_crlf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_ascii_crlf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,96 @@
+Programmers who lock onto a design decision and cling to it in the face of
+contradictory new information -- well, that's almost everyone in my
+experience, so I better not say what I think of them or people will start
+saying bad things about me on c.l.l.
+ -- Ken Tilton
+%
+This reminds me of the NYC cabby who accepted a fare to Chicago. When
+they got there and could not find the friend who was supposed to pay the
+fare he just laughed and said he should have known.
+ -- Ken Tilton
+%
+>> Actually, I believe that Aikido, Jazz and Lisp are different appearances
+>> of the same thing.
+Yes, the Tao. /Everything/ is a different appearance of the tao.
+ -- Ken Tilton
+
+"Ken, I went to the library and read up on Buddhism, and believe me, you
+are no Buddhist."
+ -- Kenny's mom
+%
+That absolutely terrifies the herd-following, lockstep-marching,
+mainstream-saluting cowards that obediently dash out or online to
+scoop up books on The Latest Thing. They learn and use atrocities like
+Java, C++, XML, and even Python for the security it gives them and
+then sit there slaving away miserably, tediously, joylously paying off
+mortgages and supporting ungrateful teenagers who despise them, only
+to look out the double-sealed thermo-pane windows of their
+central-heated, sound-proofed, dead-bolted, suffocating little nests
+into the howling gale thinking "what do they know that I do not know?"
+when they see us under a lean-to hunched over our laptops to shield
+them from the rain laughing our asses off as we write great code
+between bong hits.... what was the question?
+ -- Ken Tilton
+%
+Shut up! (That last phrase has four or more syllables if pronounced as
+intended.)
+ -- Ken Tilton
+%
+Nonsense. You'll be using it for the GUI, not protein-folding.
+ -- Ken Tilton
+ (responding to a comment that LTK was slow because it
+ was based on TK)
+%
+Continuations certainly are clever, but if we learned anything from the
+rejection of the cover art for "Smell the Glove", it is that "there is a
+fine line between stupid... and clever".
+ -- Ken Tilton
+%
+Ah, there's no place like academia for dispassionate, intellectually
+honest discussion of new ideas on their merits. Thank god for tenure
+giving your bold antagonist the protection they needed to shout down
+your iconoclastic..... hang on...
+ -- Ken Tilton
+%
+Whoever objected must be in my killfile, ...
+ -- Ken Tilton
+%
+From memory (but I think I have it right):
+
+"But Jesus said, Suffer captured variables, and forbid them not, to come
+unto thine macro bodies: for of such is are DSLs made."
+ -- Ken Tilton
+
+Can I get an Amen?
+%
+Awareness of defect is the first step to recovery.
+ -- Ken Tilton
+%
+You made a bad analogy (there are no good ones, but you found a new
+low) ...
+ -- Ken Tilton
+%
+Yes, it is true that Kent Pitman was raised by a closet full of Lisp
+Machines, but the exception only proves the rule.
+ -- Ken Tilton
+ (in a postscript after positing that computer
+ languages are not learned in infancy)
+%
+I suggest you try bartender's school to support yourself, start
+programming for fun again.
+ -- Ken Tilton
+ (responding to a comment that 98% of anything to do
+ with computers was not interesting code)
+%
+You could add four lanes to my carpal tunnel and I still could not
+write all the code I am dying to write.
+ -- Ken Tilton
+%
+Neutrality? I want to bury other languages, not have a gateway to them.
+ -- Ken Tilton
+%
+Ken: "Cute puppy. Did you get it for companionship or to pick up chicks?"
+Simon: "Hunh? My puppy /always/ gives me companionship."
+ -- Ken Tilton
+ (on how he was understood by a native english speaker)
+%
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_ascii_lf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_ascii_lf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_ascii_lf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,96 @@
+Programmers who lock onto a design decision and cling to it in the face of
+contradictory new information -- well, that's almost everyone in my
+experience, so I better not say what I think of them or people will start
+saying bad things about me on c.l.l.
+ -- Ken Tilton
+%
+This reminds me of the NYC cabby who accepted a fare to Chicago. When
+they got there and could not find the friend who was supposed to pay the
+fare he just laughed and said he should have known.
+ -- Ken Tilton
+%
+>> Actually, I believe that Aikido, Jazz and Lisp are different appearances
+>> of the same thing.
+Yes, the Tao. /Everything/ is a different appearance of the tao.
+ -- Ken Tilton
+
+"Ken, I went to the library and read up on Buddhism, and believe me, you
+are no Buddhist."
+ -- Kenny's mom
+%
+That absolutely terrifies the herd-following, lockstep-marching,
+mainstream-saluting cowards that obediently dash out or online to
+scoop up books on The Latest Thing. They learn and use atrocities like
+Java, C++, XML, and even Python for the security it gives them and
+then sit there slaving away miserably, tediously, joylously paying off
+mortgages and supporting ungrateful teenagers who despise them, only
+to look out the double-sealed thermo-pane windows of their
+central-heated, sound-proofed, dead-bolted, suffocating little nests
+into the howling gale thinking "what do they know that I do not know?"
+when they see us under a lean-to hunched over our laptops to shield
+them from the rain laughing our asses off as we write great code
+between bong hits.... what was the question?
+ -- Ken Tilton
+%
+Shut up! (That last phrase has four or more syllables if pronounced as
+intended.)
+ -- Ken Tilton
+%
+Nonsense. You'll be using it for the GUI, not protein-folding.
+ -- Ken Tilton
+ (responding to a comment that LTK was slow because it
+ was based on TK)
+%
+Continuations certainly are clever, but if we learned anything from the
+rejection of the cover art for "Smell the Glove", it is that "there is a
+fine line between stupid... and clever".
+ -- Ken Tilton
+%
+Ah, there's no place like academia for dispassionate, intellectually
+honest discussion of new ideas on their merits. Thank god for tenure
+giving your bold antagonist the protection they needed to shout down
+your iconoclastic..... hang on...
+ -- Ken Tilton
+%
+Whoever objected must be in my killfile, ...
+ -- Ken Tilton
+%
+From memory (but I think I have it right):
+
+"But Jesus said, Suffer captured variables, and forbid them not, to come
+unto thine macro bodies: for of such is are DSLs made."
+ -- Ken Tilton
+
+Can I get an Amen?
+%
+Awareness of defect is the first step to recovery.
+ -- Ken Tilton
+%
+You made a bad analogy (there are no good ones, but you found a new
+low) ...
+ -- Ken Tilton
+%
+Yes, it is true that Kent Pitman was raised by a closet full of Lisp
+Machines, but the exception only proves the rule.
+ -- Ken Tilton
+ (in a postscript after positing that computer
+ languages are not learned in infancy)
+%
+I suggest you try bartender's school to support yourself, start
+programming for fun again.
+ -- Ken Tilton
+ (responding to a comment that 98% of anything to do
+ with computers was not interesting code)
+%
+You could add four lanes to my carpal tunnel and I still could not
+write all the code I am dying to write.
+ -- Ken Tilton
+%
+Neutrality? I want to bury other languages, not have a gateway to them.
+ -- Ken Tilton
+%
+Ken: "Cute puppy. Did you get it for companionship or to pick up chicks?"
+Simon: "Hunh? My puppy /always/ gives me companionship."
+ -- Ken Tilton
+ (on how he was understood by a native english speaker)
+%
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_utf8_cr.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_utf8_cr.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_utf8_cr.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1 @@
+Programmers who lock onto a design decision and cling to it in the face of
contradictory new information -- well, that's almost everyone in my
experience, so I better not say what I think of them or people will start
saying bad things about me on c.l.l.
-- Ken Tilton
%
This reminds me of the NYC cabby who accepted a fare to Chicago. When
they got there and could not find the friend who was supposed to pay the
fare he just laughed and said he should have known.
-- Ken Tilton
%
>> Actually, I believe that Aikido, Jazz and Lisp are different appearances
>> of the same thing.
Yes, the Tao. /Everything/ is a different appearance of the tao.
-- Ken Tilton
"Ken, I went to the library and read up on Buddhism, and believe me, you
are no Buddhist."
-- Kenny's mom
%
That absolutely terrifies the herd-following, lockstep-marching,
mainstream-saluting cowards that obediently dash out or online to
scoop up books on The Latest Thing. They learn and use atrocities like
Java, C++, XML, and even Python for the security it gives them and
then sit there slaving away miserably, tediously, joylously paying off
mortgages and supporting ungrateful teenagers who despise them, only
to look out the double-sealed thermo-pane windows of their
central-heated, sound-proofed, dead-bolted, suffocating little nests
into the howling gale thinking "what do they know that I do not know?"
when they see us under a lean-to hunched over our laptops to shield
them from the rain laughing our asses off as we write great code
between bong hits.... what was the question?
-- Ken Tilton
%
Shut up! (That last phrase has four or more syllables if pronounced as
intended.)
-- Ken Tilton
%
Nonsense. You'll be using it for the GUI, not protein-folding.
-- Ken Tilton
(responding to a comment that LTK was slow because it
was based on TK)
%
Continuations certainly are clever, but if we learned anything from the
rejection of the cover art for "Smell the Glove", it is that "there is a
fine line between stupid... and clever".
-- Ken Tilton
%
Ah, there's no place like academia for dispassionate, intellectually
honest discussion of new ideas on their merits. Thank god for tenure
giving your bold antagonist the protection they needed to shout down
your iconoclastic..... hang on...
-- Ken Tilton
%
Whoever objected must be in my killfile, ...
-- Ken Tilton
%
From memory (but I think I have it right):
"But Jesus said, Suffer captured variables, and forbid them not, to come
unto thine macro bodies: for of such is are DSLs made."
-- Ken Tilton
Can I get an Amen?
%
Awareness of defect is the first step to recovery.
-- Ken Tilton
%
You made a bad analogy (there are no good ones, but you found a new
low) ...
-- Ken Tilton
%
Yes, it is true that Kent Pitman was raised by a closet full of Lisp
Machines, but the exception only proves the rule.
-- Ken Tilton
(in a postscript after positing that computer
languages are not learned in infancy)
%
I suggest you try bartender's school to support yourself, start
programming for fun again.
-- Ken Tilton
(responding to a comment that 98% of anything to do
with computers was not interesting code)
%
You could add four lanes to my carpal tunnel and I still could not
write all the code I am dying to write.
-- Ken Tilton
%
Neutrality? I want to bury other languages, not have a gateway to them.
-- Ken Tilton
%
Ken: "Cute puppy. Did you get it for companionship or to pick up chicks?"
Simon: "Hunh? My puppy /always/ gives me companionship."
-- Ken Tilton
(on how he was understood by a native english speaker)
%
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_utf8_crlf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_utf8_crlf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_utf8_crlf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,96 @@
+Programmers who lock onto a design decision and cling to it in the face of
+contradictory new information -- well, that's almost everyone in my
+experience, so I better not say what I think of them or people will start
+saying bad things about me on c.l.l.
+ -- Ken Tilton
+%
+This reminds me of the NYC cabby who accepted a fare to Chicago. When
+they got there and could not find the friend who was supposed to pay the
+fare he just laughed and said he should have known.
+ -- Ken Tilton
+%
+>> Actually, I believe that Aikido, Jazz and Lisp are different appearances
+>> of the same thing.
+Yes, the Tao. /Everything/ is a different appearance of the tao.
+ -- Ken Tilton
+
+"Ken, I went to the library and read up on Buddhism, and believe me, you
+are no Buddhist."
+ -- Kenny's mom
+%
+That absolutely terrifies the herd-following, lockstep-marching,
+mainstream-saluting cowards that obediently dash out or online to
+scoop up books on The Latest Thing. They learn and use atrocities like
+Java, C++, XML, and even Python for the security it gives them and
+then sit there slaving away miserably, tediously, joylously paying off
+mortgages and supporting ungrateful teenagers who despise them, only
+to look out the double-sealed thermo-pane windows of their
+central-heated, sound-proofed, dead-bolted, suffocating little nests
+into the howling gale thinking "what do they know that I do not know?"
+when they see us under a lean-to hunched over our laptops to shield
+them from the rain laughing our asses off as we write great code
+between bong hits.... what was the question?
+ -- Ken Tilton
+%
+Shut up! (That last phrase has four or more syllables if pronounced as
+intended.)
+ -- Ken Tilton
+%
+Nonsense. You'll be using it for the GUI, not protein-folding.
+ -- Ken Tilton
+ (responding to a comment that LTK was slow because it
+ was based on TK)
+%
+Continuations certainly are clever, but if we learned anything from the
+rejection of the cover art for "Smell the Glove", it is that "there is a
+fine line between stupid... and clever".
+ -- Ken Tilton
+%
+Ah, there's no place like academia for dispassionate, intellectually
+honest discussion of new ideas on their merits. Thank god for tenure
+giving your bold antagonist the protection they needed to shout down
+your iconoclastic..... hang on...
+ -- Ken Tilton
+%
+Whoever objected must be in my killfile, ...
+ -- Ken Tilton
+%
+From memory (but I think I have it right):
+
+"But Jesus said, Suffer captured variables, and forbid them not, to come
+unto thine macro bodies: for of such is are DSLs made."
+ -- Ken Tilton
+
+Can I get an Amen?
+%
+Awareness of defect is the first step to recovery.
+ -- Ken Tilton
+%
+You made a bad analogy (there are no good ones, but you found a new
+low) ...
+ -- Ken Tilton
+%
+Yes, it is true that Kent Pitman was raised by a closet full of Lisp
+Machines, but the exception only proves the rule.
+ -- Ken Tilton
+ (in a postscript after positing that computer
+ languages are not learned in infancy)
+%
+I suggest you try bartender's school to support yourself, start
+programming for fun again.
+ -- Ken Tilton
+ (responding to a comment that 98% of anything to do
+ with computers was not interesting code)
+%
+You could add four lanes to my carpal tunnel and I still could not
+write all the code I am dying to write.
+ -- Ken Tilton
+%
+Neutrality? I want to bury other languages, not have a gateway to them.
+ -- Ken Tilton
+%
+Ken: "Cute puppy. Did you get it for companionship or to pick up chicks?"
+Simon: "Hunh? My puppy /always/ gives me companionship."
+ -- Ken Tilton
+ (on how he was understood by a native english speaker)
+%
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_utf8_lf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_utf8_lf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/tilton_utf8_lf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,96 @@
+Programmers who lock onto a design decision and cling to it in the face of
+contradictory new information -- well, that's almost everyone in my
+experience, so I better not say what I think of them or people will start
+saying bad things about me on c.l.l.
+ -- Ken Tilton
+%
+This reminds me of the NYC cabby who accepted a fare to Chicago. When
+they got there and could not find the friend who was supposed to pay the
+fare he just laughed and said he should have known.
+ -- Ken Tilton
+%
+>> Actually, I believe that Aikido, Jazz and Lisp are different appearances
+>> of the same thing.
+Yes, the Tao. /Everything/ is a different appearance of the tao.
+ -- Ken Tilton
+
+"Ken, I went to the library and read up on Buddhism, and believe me, you
+are no Buddhist."
+ -- Kenny's mom
+%
+That absolutely terrifies the herd-following, lockstep-marching,
+mainstream-saluting cowards that obediently dash out or online to
+scoop up books on The Latest Thing. They learn and use atrocities like
+Java, C++, XML, and even Python for the security it gives them and
+then sit there slaving away miserably, tediously, joylously paying off
+mortgages and supporting ungrateful teenagers who despise them, only
+to look out the double-sealed thermo-pane windows of their
+central-heated, sound-proofed, dead-bolted, suffocating little nests
+into the howling gale thinking "what do they know that I do not know?"
+when they see us under a lean-to hunched over our laptops to shield
+them from the rain laughing our asses off as we write great code
+between bong hits.... what was the question?
+ -- Ken Tilton
+%
+Shut up! (That last phrase has four or more syllables if pronounced as
+intended.)
+ -- Ken Tilton
+%
+Nonsense. You'll be using it for the GUI, not protein-folding.
+ -- Ken Tilton
+ (responding to a comment that LTK was slow because it
+ was based on TK)
+%
+Continuations certainly are clever, but if we learned anything from the
+rejection of the cover art for "Smell the Glove", it is that "there is a
+fine line between stupid... and clever".
+ -- Ken Tilton
+%
+Ah, there's no place like academia for dispassionate, intellectually
+honest discussion of new ideas on their merits. Thank god for tenure
+giving your bold antagonist the protection they needed to shout down
+your iconoclastic..... hang on...
+ -- Ken Tilton
+%
+Whoever objected must be in my killfile, ...
+ -- Ken Tilton
+%
+From memory (but I think I have it right):
+
+"But Jesus said, Suffer captured variables, and forbid them not, to come
+unto thine macro bodies: for of such is are DSLs made."
+ -- Ken Tilton
+
+Can I get an Amen?
+%
+Awareness of defect is the first step to recovery.
+ -- Ken Tilton
+%
+You made a bad analogy (there are no good ones, but you found a new
+low) ...
+ -- Ken Tilton
+%
+Yes, it is true that Kent Pitman was raised by a closet full of Lisp
+Machines, but the exception only proves the rule.
+ -- Ken Tilton
+ (in a postscript after positing that computer
+ languages are not learned in infancy)
+%
+I suggest you try bartender's school to support yourself, start
+programming for fun again.
+ -- Ken Tilton
+ (responding to a comment that 98% of anything to do
+ with computers was not interesting code)
+%
+You could add four lanes to my carpal tunnel and I still could not
+write all the code I am dying to write.
+ -- Ken Tilton
+%
+Neutrality? I want to bury other languages, not have a gateway to them.
+ -- Ken Tilton
+%
+Ken: "Cute puppy. Did you get it for companionship or to pick up chicks?"
+Simon: "Hunh? My puppy /always/ gives me companionship."
+ -- Ken Tilton
+ (on how he was understood by a native english speaker)
+%
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_cr_be.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_cr_be.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_cr_le.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_cr_le.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_crlf_be.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_crlf_be.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_crlf_le.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_crlf_le.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_lf_be.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_lf_be.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_lf_le.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs2_lf_le.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_cr_be.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_cr_be.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_cr_le.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_cr_le.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_crlf_be.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_crlf_be.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_crlf_le.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_crlf_le.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_lf_be.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_lf_be.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_lf_le.txt
===================================================================
(Binary files differ)
Property changes on: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_ucs4_lf_le.txt
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_utf8_cr.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_utf8_cr.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_utf8_cr.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1 @@
+
UTF-8 encoded sample plain-text file
‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
Markus Kuhn [ˈmaʳkʊs kuːn] <http://www.cl.cam.ac.uk/~mgk25/> — 2002-07-25
The ASCII compatible UTF-8 encoding used in this plain-text file
is defined in Unicode, ISO 10646-1, and RFC 2279.
Using Unicode/UTF-8, you can write in emails and source code things such as
Mathematics and sciences:
∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ⎧⎡⎛┌─────┐⎞⎤⎫
⎪⎢⎜│a²+b³ ⎟⎥⎪
∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β), ⎪⎢⎜│───── ⎟⎥⎪
⎪⎢⎜⎷ c₈ ⎟⎥⎪
ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⎨⎢⎜ ⎟⎥⎬
⎪⎢⎜ ∞ ⎟⎥⎪
⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (⟦A⟧ ⇔ ⟪B⟫), ⎪⎢⎜ ⎲ ⎟⎥⎪
⎪⎢⎜ ⎳aⁱ-bⁱ⎟⎥⎪
2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm ⎩⎣⎝i=1 ⎠⎦⎭
Linguistics and dictionaries:
ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn
Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ]
APL:
((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈
Nicer typography in plain text files:
╔══════════════════════════════════════════╗
║ ║
║ • ‘single’ and “double” quotes ║
║ ║
║ • Curly apostrophes: “We’ve been here” ║
║ ║
║ • Latin-1 apostrophe and accents: '´` ║
║ ║
║ • ‚deutsche‘ „Anführungszeichen“ ║
║ ║
║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║
║ ║
║ • ASCII safety test: 1lI|, 0OD, 8B ║
║ ╭─────────╮ ║
║ • the euro symbol: │ 14.95 € │ ║
║ ╰─────────╯ ║
╚══════════════════════════════════════════╝
Combining characters:
STARGΛ̊TE SG-1, a = v̇ = r̈, a⃑ ⊥ b⃑
Greek (in Polytonic):
The Greek anthem:
Σὲ γνωρίζω ἀπὸ τὴν κόψη
τοῦ σπαθιοῦ τὴν τρομερή,
σὲ γνωρίζω ἀπὸ τὴν ὄψη
ποὺ μὲ βία μετράει τὴ γῆ.
᾿Απ᾿ τὰ κόκκαλα βγαλμένη
τῶν ῾Ελλήνων τὰ ἱερά
καὶ σὰν πρῶτα ἀνδρειωμένη
χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά!
From a speech of Demosthenes in the 4th century BC:
Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι,
ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς
λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ
τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿
εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ
πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν
οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι,
οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν
ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον
τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι
γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν
προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους
σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ
τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ
τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς
τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον.
Δημοσθένους, Γ´ ᾿Ολυνθιακὸς
Georgian:
From a Unicode conference invitation:
გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო
კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს,
ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს
ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი,
ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება
ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში,
ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში.
Russian:
From a Unicode conference invitation:
Зарегистрируйтесь сейчас на Десятую Международную Конференцию по
Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии.
Конференция соберет широкий круг экспертов по вопросам глобального
Интернета и Unicode, локализации и интернационализации, воплощению и
применению Unicode в различных операционных системах и программных
приложениях, шрифтах, верстке и многоязычных компьютерных системах.
Thai (UCS Level 2):
Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese
classic 'San Gua'):
[----------------------------|------------------------]
๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่
สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา
ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา
โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ
เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ
ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ
พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้
ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ
(The above is a two-column text. If combining characters are handled
correctly, the lines of the second column should be aligned with the
| character above.)
Ethiopian:
Proverbs in the Amharic language:
ሰማይ አይታረስ ንጉሥ አይከሰስ።
ብላ ካለኝ እንደአባቴ በቆመጠኝ።
ጌጥ ያለቤቱ ቁምጥና ነው።
ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው።
የአፍ ወለምታ በቅቤ አይታሽም።
አይጥ በበላ ዳዋ ተመታ።
ሲተረጉሙ ይደረግሙ።
ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል።
ድር ቢያብር አንበሳ ያስር።
ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም።
እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም።
የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ።
ሥራ ከመፍታት ልጄን ላፋታት።
ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል።
የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ።
ተንጋሎ ቢተፉ ተመልሶ ባፉ።
ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው።
እግርህን በፍራሽህ ልክ ዘርጋ።
Runes:
ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ
(Old English, which transcribed into Latin reads 'He cwaeth that he
bude thaem lande northweardum with tha Westsae.' and means 'He said
that he lived in the northern land near the Western Sea.')
Braille:
⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌
⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞
⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎
⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂
⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙
⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑
⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲
⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹
⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞
⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕
⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹
⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎
⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎
⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳
⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞
⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
(The first couple of paragraphs of "A Christmas Carol" by Dickens)
Compact font selection example text:
ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789
abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ
–—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд
∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა
Greetings in various languages:
Hello world, Καλημέρα κόσμε, コンニチハ
Box drawing alignment tests: █
▉
╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
▝▀▘▙▄▟
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_utf8_crlf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_utf8_crlf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_utf8_crlf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,212 @@
+
+UTF-8 encoded sample plain-text file
+‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
+
+Markus Kuhn [ˈmaʳkʊs kuːn] <http://www.cl.cam.ac.uk/~mgk25/> — 2002-07-25
+
+
+The ASCII compatible UTF-8 encoding used in this plain-text file
+is defined in Unicode, ISO 10646-1, and RFC 2279.
+
+
+Using Unicode/UTF-8, you can write in emails and source code things such as
+
+Mathematics and sciences:
+
+ ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ⎧⎡⎛┌─────┐⎞⎤⎫
+ ⎪⎢⎜│a²+b³ ⎟⎥⎪
+ ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β), ⎪⎢⎜│───── ⎟⎥⎪
+ ⎪⎢⎜⎷ c₈ ⎟⎥⎪
+ ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⎨⎢⎜ ⎟⎥⎬
+ ⎪⎢⎜ ∞ ⎟⎥⎪
+ ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (⟦A⟧ ⇔ ⟪B⟫), ⎪⎢⎜ ⎲ ⎟⎥⎪
+ ⎪⎢⎜ ⎳aⁱ-bⁱ⎟⎥⎪
+ 2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm ⎩⎣⎝i=1 ⎠⎦⎭
+
+Linguistics and dictionaries:
+
+ ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn
+ Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ]
+
+APL:
+
+ ((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈
+
+Nicer typography in plain text files:
+
+ ╔══════════════════════════════════════════╗
+ ║ ║
+ ║ • ‘single’ and “double” quotes ║
+ ║ ║
+ ║ • Curly apostrophes: “We’ve been here” ║
+ ║ ║
+ ║ • Latin-1 apostrophe and accents: '´` ║
+ ║ ║
+ ║ • ‚deutsche‘ „Anführungszeichen“ ║
+ ║ ║
+ ║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║
+ ║ ║
+ ║ • ASCII safety test: 1lI|, 0OD, 8B ║
+ ║ ╭─────────╮ ║
+ ║ • the euro symbol: │ 14.95 € │ ║
+ ║ ╰─────────╯ ║
+ ╚══════════════════════════════════════════╝
+
+Combining characters:
+
+ STARGΛ̊TE SG-1, a = v̇ = r̈, a⃑ ⊥ b⃑
+
+Greek (in Polytonic):
+
+ The Greek anthem:
+
+ Σὲ γνωρίζω ἀπὸ τὴν κόψη
+ τοῦ σπαθιοῦ τὴν τρομερή,
+ σὲ γνωρίζω ἀπὸ τὴν ὄψη
+ ποὺ μὲ βία μετράει τὴ γῆ.
+
+ ᾿Απ᾿ τὰ κόκκαλα βγαλμένη
+ τῶν ῾Ελλήνων τὰ ἱερά
+ καὶ σὰν πρῶτα ἀνδρειωμένη
+ χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά!
+
+ From a speech of Demosthenes in the 4th century BC:
+
+ Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι,
+ ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς
+ λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ
+ τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿
+ εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ
+ πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν
+ οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι,
+ οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν
+ ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον
+ τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι
+ γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν
+ προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους
+ σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ
+ τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ
+ τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς
+ τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον.
+
+ Δημοσθένους, Γ´ ᾿Ολυνθιακὸς
+
+Georgian:
+
+ From a Unicode conference invitation:
+
+ გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო
+ კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს,
+ ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს
+ ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი,
+ ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება
+ ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში,
+ ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში.
+
+Russian:
+
+ From a Unicode conference invitation:
+
+ Зарегистрируйтесь сейчас на Десятую Международную Конференцию по
+ Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии.
+ Конференция соберет широкий круг экспертов по вопросам глобального
+ Интернета и Unicode, локализации и интернационализации, воплощению и
+ применению Unicode в различных операционных системах и программных
+ приложениях, шрифтах, верстке и многоязычных компьютерных системах.
+
+Thai (UCS Level 2):
+
+ Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese
+ classic 'San Gua'):
+
+ [----------------------------|------------------------]
+ ๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่
+ สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา
+ ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา
+ โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ
+ เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ
+ ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ
+ พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้
+ ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ
+
+ (The above is a two-column text. If combining characters are handled
+ correctly, the lines of the second column should be aligned with the
+ | character above.)
+
+Ethiopian:
+
+ Proverbs in the Amharic language:
+
+ ሰማይ አይታረስ ንጉሥ አይከሰስ።
+ ብላ ካለኝ እንደአባቴ በቆመጠኝ።
+ ጌጥ ያለቤቱ ቁምጥና ነው።
+ ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው።
+ የአፍ ወለምታ በቅቤ አይታሽም።
+ አይጥ በበላ ዳዋ ተመታ።
+ ሲተረጉሙ ይደረግሙ።
+ ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል።
+ ድር ቢያብር አንበሳ ያስር።
+ ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም።
+ እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም።
+ የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ።
+ ሥራ ከመፍታት ልጄን ላፋታት።
+ ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል።
+ የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ።
+ ተንጋሎ ቢተፉ ተመልሶ ባፉ።
+ ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው።
+ እግርህን በፍራሽህ ልክ ዘርጋ።
+
+Runes:
+
+ ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ
+
+ (Old English, which transcribed into Latin reads 'He cwaeth that he
+ bude thaem lande northweardum with tha Westsae.' and means 'He said
+ that he lived in the northern land near the Western Sea.')
+
+Braille:
+
+ ⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌
+
+ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞
+ ⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎
+ ⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂
+ ⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙
+ ⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑
+ ⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲
+
+ ⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
+
+ ⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹
+ ⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞
+ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕
+ ⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹
+ ⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎
+ ⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎
+ ⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳
+ ⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞
+ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
+
+ (The first couple of paragraphs of "A Christmas Carol" by Dickens)
+
+Compact font selection example text:
+
+ ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789
+ abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ
+ –—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд
+ ∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა
+
+Greetings in various languages:
+
+ Hello world, Καλημέρα κόσμε, コンニチハ
+
+Box drawing alignment tests: █
+ ▉
+ ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
+ ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
+ ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
+ ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
+ ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
+ ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
+ ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
+ ▝▀▘▙▄▟
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_utf8_lf.txt
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_utf8_lf.txt 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/test/unicode_demo_utf8_lf.txt 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,212 @@
+
+UTF-8 encoded sample plain-text file
+‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
+
+Markus Kuhn [ˈmaʳkʊs kuːn] <http://www.cl.cam.ac.uk/~mgk25/> — 2002-07-25
+
+
+The ASCII compatible UTF-8 encoding used in this plain-text file
+is defined in Unicode, ISO 10646-1, and RFC 2279.
+
+
+Using Unicode/UTF-8, you can write in emails and source code things such as
+
+Mathematics and sciences:
+
+ ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ⎧⎡⎛┌─────┐⎞⎤⎫
+ ⎪⎢⎜│a²+b³ ⎟⎥⎪
+ ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β), ⎪⎢⎜│───── ⎟⎥⎪
+ ⎪⎢⎜⎷ c₈ ⎟⎥⎪
+ ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⎨⎢⎜ ⎟⎥⎬
+ ⎪⎢⎜ ∞ ⎟⎥⎪
+ ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (⟦A⟧ ⇔ ⟪B⟫), ⎪⎢⎜ ⎲ ⎟⎥⎪
+ ⎪⎢⎜ ⎳aⁱ-bⁱ⎟⎥⎪
+ 2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm ⎩⎣⎝i=1 ⎠⎦⎭
+
+Linguistics and dictionaries:
+
+ ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn
+ Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ]
+
+APL:
+
+ ((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈
+
+Nicer typography in plain text files:
+
+ ╔══════════════════════════════════════════╗
+ ║ ║
+ ║ • ‘single’ and “double” quotes ║
+ ║ ║
+ ║ • Curly apostrophes: “We’ve been here” ║
+ ║ ║
+ ║ • Latin-1 apostrophe and accents: '´` ║
+ ║ ║
+ ║ • ‚deutsche‘ „Anführungszeichen“ ║
+ ║ ║
+ ║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║
+ ║ ║
+ ║ • ASCII safety test: 1lI|, 0OD, 8B ║
+ ║ ╭─────────╮ ║
+ ║ • the euro symbol: │ 14.95 € │ ║
+ ║ ╰─────────╯ ║
+ ╚══════════════════════════════════════════╝
+
+Combining characters:
+
+ STARGΛ̊TE SG-1, a = v̇ = r̈, a⃑ ⊥ b⃑
+
+Greek (in Polytonic):
+
+ The Greek anthem:
+
+ Σὲ γνωρίζω ἀπὸ τὴν κόψη
+ τοῦ σπαθιοῦ τὴν τρομερή,
+ σὲ γνωρίζω ἀπὸ τὴν ὄψη
+ ποὺ μὲ βία μετράει τὴ γῆ.
+
+ ᾿Απ᾿ τὰ κόκκαλα βγαλμένη
+ τῶν ῾Ελλήνων τὰ ἱερά
+ καὶ σὰν πρῶτα ἀνδρειωμένη
+ χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά!
+
+ From a speech of Demosthenes in the 4th century BC:
+
+ Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι,
+ ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς
+ λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ
+ τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿
+ εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ
+ πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν
+ οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι,
+ οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν
+ ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον
+ τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι
+ γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν
+ προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους
+ σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ
+ τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ
+ τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς
+ τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον.
+
+ Δημοσθένους, Γ´ ᾿Ολυνθιακὸς
+
+Georgian:
+
+ From a Unicode conference invitation:
+
+ გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო
+ კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს,
+ ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს
+ ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი,
+ ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება
+ ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში,
+ ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში.
+
+Russian:
+
+ From a Unicode conference invitation:
+
+ Зарегистрируйтесь сейчас на Десятую Международную Конференцию по
+ Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии.
+ Конференция соберет широкий круг экспертов по вопросам глобального
+ Интернета и Unicode, локализации и интернационализации, воплощению и
+ применению Unicode в различных операционных системах и программных
+ приложениях, шрифтах, верстке и многоязычных компьютерных системах.
+
+Thai (UCS Level 2):
+
+ Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese
+ classic 'San Gua'):
+
+ [----------------------------|------------------------]
+ ๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่
+ สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา
+ ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา
+ โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ
+ เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ
+ ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ
+ พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้
+ ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ
+
+ (The above is a two-column text. If combining characters are handled
+ correctly, the lines of the second column should be aligned with the
+ | character above.)
+
+Ethiopian:
+
+ Proverbs in the Amharic language:
+
+ ሰማይ አይታረስ ንጉሥ አይከሰስ።
+ ብላ ካለኝ እንደአባቴ በቆመጠኝ።
+ ጌጥ ያለቤቱ ቁምጥና ነው።
+ ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው።
+ የአፍ ወለምታ በቅቤ አይታሽም።
+ አይጥ በበላ ዳዋ ተመታ።
+ ሲተረጉሙ ይደረግሙ።
+ ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል።
+ ድር ቢያብር አንበሳ ያስር።
+ ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም።
+ እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም።
+ የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ።
+ ሥራ ከመፍታት ልጄን ላፋታት።
+ ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል።
+ የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ።
+ ተንጋሎ ቢተፉ ተመልሶ ባፉ።
+ ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው።
+ እግርህን በፍራሽህ ልክ ዘርጋ።
+
+Runes:
+
+ ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ
+
+ (Old English, which transcribed into Latin reads 'He cwaeth that he
+ bude thaem lande northweardum with tha Westsae.' and means 'He said
+ that he lived in the northern land near the Western Sea.')
+
+Braille:
+
+ ⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌
+
+ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞
+ ⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎
+ ⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂
+ ⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙
+ ⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑
+ ⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲
+
+ ⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
+
+ ⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹
+ ⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞
+ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕
+ ⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹
+ ⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎
+ ⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎
+ ⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳
+ ⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞
+ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲
+
+ (The first couple of paragraphs of "A Christmas Carol" by Dickens)
+
+Compact font selection example text:
+
+ ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789
+ abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ
+ –—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд
+ ∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა
+
+Greetings in various languages:
+
+ Hello world, Καλημέρα κόσμε, コンニチハ
+
+Box drawing alignment tests: █
+ ▉
+ ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
+ ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
+ ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
+ ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
+ ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
+ ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
+ ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
+ ▝▀▘▙▄▟
Added: branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/util.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/util.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/flexi-streams-0.13.1/util.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,166 @@
+;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: FLEXI-STREAMS; Base: 10 -*-
+;;; $Header: /usr/local/cvsrep/flexi-streams/util.lisp,v 1.13 2007/01/01 23:46:49 edi Exp $
+
+;;; Copyright (c) 2005-2007, Dr. Edmund Weitz. All rights reserved.
+
+;;; Redistribution and use in source and binary forms, with or without
+;;; modification, are permitted provided that the following conditions
+;;; are met:
+
+;;; * Redistributions of source code must retain the above copyright
+;;; notice, this list of conditions and the following disclaimer.
+
+;;; * Redistributions in binary form must reproduce the above
+;;; copyright notice, this list of conditions and the following
+;;; disclaimer in the documentation and/or other materials
+;;; provided with the distribution.
+
+;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(in-package :flexi-streams)
+
+#+:lispworks
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (import 'lw:with-unique-names))
+
+#-:lispworks
+(defmacro with-unique-names ((&rest bindings) &body body)
+ "Syntax: WITH-UNIQUE-NAMES ( { var | (var x) }* ) declaration* form*
+
+Executes a series of forms with each VAR bound to a fresh,
+uninterned symbol. The uninterned symbol is as if returned by a call
+to GENSYM with the string denoted by X - or, if X is not supplied, the
+string denoted by VAR - as argument.
+
+The variable bindings created are lexical unless special declarations
+are specified. The scopes of the name bindings and declarations do not
+include the Xs.
+
+The forms are evaluated in order, and the values of all but the last
+are discarded \(that is, the body is an implicit PROGN)."
+ ;; reference implementation posted to comp.lang.lisp as
+ ;; <cy3bshuf30f.fsf(a)ljosa.com> by Vebjorn Ljosa - see also
+ ;; <http://www.cliki.net/Common%20Lisp%20Utilities>
+ `(let ,(mapcar #'(lambda (binding)
+ (check-type binding (or cons symbol))
+ (if (consp binding)
+ (destructuring-bind (var x) binding
+ (check-type var symbol)
+ `(,var (gensym ,(etypecase x
+ (symbol (symbol-name x))
+ (character (string x))
+ (string x)))))
+ `(,binding (gensym ,(symbol-name binding)))))
+ bindings)
+ ,@body))
+
+#+:lispworks
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (setf (macro-function 'with-rebinding)
+ (macro-function 'lw:rebinding)))
+
+#-:lispworks
+(defmacro with-rebinding (bindings &body body)
+ "WITH-REBINDING ( { var | (var prefix) }* ) form*
+
+Evaluates a series of forms in the lexical environment that is
+formed by adding the binding of each VAR to a fresh, uninterned
+symbol, and the binding of that fresh, uninterned symbol to VAR's
+original value, i.e., its value in the current lexical environment.
+
+The uninterned symbol is created as if by a call to GENSYM with the
+string denoted by PREFIX - or, if PREFIX is not supplied, the string
+denoted by VAR - as argument.
+
+The forms are evaluated in order, and the values of all but the last
+are discarded \(that is, the body is an implicit PROGN)."
+ ;; reference implementation posted to comp.lang.lisp as
+ ;; <cy3wv0fya0p.fsf(a)ljosa.com> by Vebjorn Ljosa - see also
+ ;; <http://www.cliki.net/Common%20Lisp%20Utilities>
+ (loop for binding in bindings
+ for var = (if (consp binding) (car binding) binding)
+ for name = (gensym)
+ collect `(,name ,var) into renames
+ collect ``(,,var ,,name) into temps
+ finally (return `(let ,renames
+ (with-unique-names ,bindings
+ `(let (,,@temps)
+ ,,@body))))))
+
+(defun normalize-external-format-name (name)
+ "Converts NAME \(a symbol) to a `canonical' name for an
+external format, e.g. :LATIN1 will be converted to :ISO-8859-1.
+Also checks if there is an external format with that name and
+signals an error otherwise."
+ (let ((real-name (or (cdr (assoc name +name-map+
+ :test #'eq))
+ name)))
+ (unless (find real-name +name-map+
+ :test #'eq
+ :key #'cdr)
+ (error "~S is not known to be a name for an external format." name))
+ real-name))
+
+(defun ascii-name-p (name)
+ "Checks whether NAME is the keyword :ASCII."
+ (eq name :us-ascii))
+
+(defun koi8-r-name-p (name)
+ "Checks whether NAME is the keyword :KOI8-R."
+ (eq name :koi8-r))
+
+(defun code-page-name-p (name)
+ "Checks whether NAME is the keyword :CODE-PAGE."
+ (eq name :code-page))
+
+(defun iso-8859-name-p (name)
+ "Checks whether NAME \(a keyword) names one of the known
+ISO-8859 encodings."
+ (find name +iso-8859-tables+ :key #'car))
+
+(defun known-code-page-id-p (id)
+ "Checks whether ID \(a number) denotes one of the known Windows
+code pages."
+ (and (find id +code-page-tables+ :key #'car)
+ id))
+
+#+:lispworks
+(defun sans (plist &rest keys)
+ "Returns PLIST with keyword arguments from KEYS removed."
+ (sys::remove-properties plist keys))
+
+#-:lispworks
+(defun sans (plist &rest keys)
+ "Returns PLIST with keyword arguments from KEYS removed."
+ ;; stolen from Usenet posting <3247672165664225(a)naggum.no> by Erik
+ ;; Naggum
+ (let ((sans ()))
+ (loop
+ (let ((tail (nth-value 2 (get-properties plist keys))))
+ ;; this is how it ends
+ (unless tail
+ (return (nreconc sans plist)))
+ ;; copy all the unmatched keys
+ (loop until (eq plist tail) do
+ (push (pop plist) sans)
+ (push (pop plist) sans))
+ ;; skip the matched key
+ (setq plist (cddr plist))))))
+
+#+:lispworks
+(defmacro with-accessors (slot-entries instance &body body)
+ "For LispWorks, we prefer SLOT-VALUE over accessors for better
+performance."
+ `(with-slots ,(mapcar #'car slot-entries)
+ ,instance
+ ,@body))
\ No newline at end of file
Added: branches/trunk-reorg/thirdparty/trivial-gray-streams/COPYING
===================================================================
--- branches/trunk-reorg/thirdparty/trivial-gray-streams/COPYING 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/trivial-gray-streams/COPYING 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,21 @@
+ Copyright (c) 2005 David Lichteblau
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation files
+ (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
Added: branches/trunk-reorg/thirdparty/trivial-gray-streams/Makefile
===================================================================
--- branches/trunk-reorg/thirdparty/trivial-gray-streams/Makefile 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/trivial-gray-streams/Makefile 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,3 @@
+.PHONY: clean
+clean:
+ rm -f *.fasl *.x86f *.fas *.ufsl *.lib *.pfsl
Added: branches/trunk-reorg/thirdparty/trivial-gray-streams/README
===================================================================
--- branches/trunk-reorg/thirdparty/trivial-gray-streams/README 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/trivial-gray-streams/README 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,37 @@
+trivial-gray-streams
+====================
+
+This system provides an extremely thin compatibility layer for gray
+streams. It is nearly *too* trivial for a complete package, except that
+I have copy&pasted this code into enough projects now that I decided to
+factor it out once again now, and then *never* have to touch it again.
+
+
+How to use it
+=============
+
+1. Use the package TRIVIAL-GRAY-STREAMS instead of whatever
+ implementation-specific package you would have to use otherwise to
+ get at gray stream symbols.
+2. For STREAM-READ-SEQUENCE and STREAM-WRITE-SEQUENCE, notice that we
+ use two required arguments and allow additional keyword arguments.
+ So the lambda list when defining a method on either function should look
+ like this:
+ (stream sequence start end &key)
+3. In order for (2) to work on all Lisps, make sure to subclass all your
+ stream classes from TRIVIAL-GRAY-STREAM-MIXIN if you intend to define
+ methods on those two generic functions.
+
+
+Extensions
+==========
+
+Generic function STREAM-READ-SEQUENCE (stream sequence start end &key)
+Generic function STREAM-WRITE-SEQUENCE (stream sequence start end &key)
+
+ See above.
+
+Generic function STREAM-FILE-POSITION (stream) => file position
+Generic function (SETF STREAM-FILE-POSITION) (position-spec stream) => successp
+
+ Will only be called by LispWorks and CLISP.
Added: branches/trunk-reorg/thirdparty/trivial-gray-streams/mixin.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/trivial-gray-streams/mixin.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/trivial-gray-streams/mixin.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,117 @@
+(in-package :trivial-gray-streams)
+
+(defclass trivial-gray-stream-mixin () ())
+
+(defgeneric stream-read-sequence
+ (stream sequence start end &key &allow-other-keys))
+(defgeneric stream-write-sequence
+ (stream sequence start end &key &allow-other-keys))
+
+(defgeneric stream-file-position (stream))
+(defgeneric (setf stream-file-position) (newval stream))
+
+(defmethod stream-write-string
+ ((stream trivial-gray-stream-mixin) seq &optional start end)
+ (stream-write-sequence stream seq (or start 0) (or end (length seq))))
+
+;; Implementations should provide this default method, I believe, but
+;; at least sbcl and allegro don't.
+(defmethod stream-terpri ((stream trivial-gray-stream-mixin))
+ (write-char #\newline stream))
+
+(defmethod stream-file-position ((stream trivial-gray-stream-mixin))
+ nil)
+
+(defmethod (setf stream-file-position)
+ (newval (stream trivial-gray-stream-mixin))
+ (declare (ignore newval))
+ nil)
+
+#+allegro
+(progn
+ (defmethod excl:stream-read-sequence
+ ((s trivial-gray-stream-mixin) seq &optional start end)
+ (stream-read-sequence s seq (or start 0) (or end (length seq))))
+ (defmethod stream:stream-write-sequence
+ ((s trivial-gray-stream-mixin) seq &optional start end)
+ (stream-write-sequence s seq (or start 0) (or end (length seq)))))
+
+#+cmu
+(progn
+ (defmethod ext:stream-read-sequence
+ ((s trivial-gray-stream-mixin) seq &optional start end)
+ (stream-read-sequence s seq (or start 0) (or end (length seq))))
+ (defmethod ext:stream-write-sequence
+ ((s trivial-gray-stream-mixin) seq &optional start end)
+ (stream-write-sequence s seq (or start 0) (or end (length seq)))))
+
+#+lispworks
+(progn
+ (defmethod stream:stream-read-sequence
+ ((s trivial-gray-stream-mixin) seq start end)
+ (stream-read-sequence s seq start end))
+ (defmethod stream:stream-write-sequence
+ ((s trivial-gray-stream-mixin) seq start end)
+ (stream-write-sequence s seq start end))
+
+ (defmethod stream:stream-file-position ((stream trivial-gray-stream-mixin))
+ (stream-file-position stream))
+ (defmethod (setf stream:stream-file-position)
+ (newval (stream trivial-gray-stream-mixin))
+ (setf (stream-file-position stream) newval)))
+
+#+openmcl
+(progn
+ (defmethod ccl:stream-read-vector
+ ((s trivial-gray-stream-mixin) seq start end)
+ (stream-read-sequence s seq start end))
+ (defmethod ccl:stream-write-vector
+ ((s trivial-gray-stream-mixin) seq start end)
+ (stream-write-sequence s seq start end)))
+
+#+clisp
+(progn
+ (defmethod gray:stream-read-byte-sequence
+ ((s trivial-gray-stream-mixin)
+ seq
+ &optional start end no-hang interactive)
+ (when no-hang
+ (error "this stream does not support the NO-HANG argument"))
+ (when interactive
+ (error "this stream does not support the INTERACTIVE argument"))
+ (stream-read-sequence s seq start end))
+
+ (defmethod gray:stream-write-byte-sequence
+ ((s trivial-gray-stream-mixin)
+ seq
+ &optional start end no-hang interactive)
+ (when no-hang
+ (error "this stream does not support the NO-HANG argument"))
+ (when interactive
+ (error "this stream does not support the INTERACTIVE argument"))
+ (stream-write-sequence s seq start end))
+
+ (defmethod gray:stream-read-char-sequence
+ ((s trivial-gray-stream-mixin) seq &optional start end)
+ (stream-read-sequence s seq start end))
+
+ (defmethod gray:stream-write-char-sequence
+ ((s trivial-gray-stream-mixin) seq &optional start end)
+ (stream-write-sequence s seq start end))
+
+ (defmethod gray:stream-position ((stream trivial-gray-stream-mixin) position)
+ (if position
+ (setf (stream-file-position stream) position)
+ (stream-file-position stream))))
+
+#+sbcl
+(progn
+ (defmethod sb-gray:stream-read-sequence
+ ((s trivial-gray-stream-mixin) seq &optional start end)
+ (stream-read-sequence s seq (or start 0) (or end (length seq))))
+ (defmethod sb-gray:stream-write-sequence
+ ((s trivial-gray-stream-mixin) seq &optional start end)
+ (stream-write-sequence s seq (or start 0) (or end (length seq))))
+ ;; SBCL extension:
+ (defmethod sb-gray:stream-line-length ((stream trivial-gray-stream-mixin))
+ 80))
Added: branches/trunk-reorg/thirdparty/trivial-gray-streams/package.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/trivial-gray-streams/package.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/trivial-gray-streams/package.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,44 @@
+(in-package :trivial-gray-streams-system)
+
+#+cmu
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (require :gray-streams))
+
+#+allegro
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (unless (fboundp 'stream:stream-write-string)
+ (require "streamc.fasl")))
+
+(macrolet
+ ((frob ()
+ (let
+ ((common-symbols
+ '(#:fundamental-stream #:fundamental-input-stream
+ #:fundamental-output-stream #:fundamental-character-stream
+ #:fundamental-binary-stream #:fundamental-character-input-stream
+ #:fundamental-character-output-stream
+ #:fundamental-binary-input-stream
+ #:fundamental-binary-output-stream #:stream-read-char
+ #:stream-unread-char #:stream-read-char-no-hang
+ #:stream-peek-char #:stream-listen #:stream-read-line
+ #:stream-clear-input #:stream-write-char #:stream-line-column
+ #:stream-start-line-p #:stream-write-string #:stream-terpri
+ #:stream-fresh-line #:stream-finish-output #:stream-force-output
+ #:stream-clear-output #:stream-advance-to-column
+ #:stream-read-byte #:stream-write-byte)))
+ `(defpackage :trivial-gray-streams
+ (:use :cl)
+ (:import-from #+sbcl :sb-gray
+ #+allegro :excl
+ #+cmu :ext
+ #+clisp :gray
+ #+openmcl :ccl
+ #+lispworks :stream
+ #-(or sbcl allegro cmu clisp openmcl lispworks) ...
+ ,@common-symbols)
+ (:export #:trivial-gray-stream-mixin
+ #:stream-read-sequence
+ #:stream-write-sequence
+ #:stream-file-position
+ ,@common-symbols)))))
+ (frob))
Added: branches/trunk-reorg/thirdparty/trivial-gray-streams/trivial-gray-streams.asd
===================================================================
--- branches/trunk-reorg/thirdparty/trivial-gray-streams/trivial-gray-streams.asd 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/trivial-gray-streams/trivial-gray-streams.asd 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,9 @@
+;;; -*- mode: lisp -*-
+
+(defpackage :trivial-gray-streams-system
+(:use :cl :asdf))
+(in-package :trivial-gray-streams-system)
+
+(defsystem :trivial-gray-streams
+ :serial t
+ :components ((:file "package") (:file "mixin")))
Added: branches/trunk-reorg/thirdparty/trivial-https/LICENSE
===================================================================
--- branches/trunk-reorg/thirdparty/trivial-https/LICENSE 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/trivial-https/LICENSE 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,21 @@
+Copyright (c) 2005 Brian Mastenbrook
+[ HTTPS support 2005 David Lichteblau ]
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Added: branches/trunk-reorg/thirdparty/trivial-https/README
===================================================================
--- branches/trunk-reorg/thirdparty/trivial-https/README 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/trivial-https/README 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,18 @@
+[ trivial-https is a fork of trivial-http with support for HTTPS. ]
+
+trivial-https is a trivial library for doing HTTP POST and GET over a
+socket interface. It establishes a package TRIVIAL-HTTPS, from which the
+following functions are exported:
+
+(TRIVIAL-HTTPS:HTTP-GET URL &optional HEADERS) - returns a list of three
+elements: a response code as integer, an association list of headers returned
+from the server, and a stream from which the request can be read. Optional
+argument HEADERS can be supplied as an alist of header name and value pairs
+to be sent to the server.
+
+(TRIVIAL-HTTPS:HTTP-POST URL CONTENT-TYPE CONTENT) - given a URL, a MIME
+content type, and the content as a character stream, POST to the URL
+and return the list of three elements as described for HTTP-GET.
+
+(TRIVIAL-HTTPS:ESCAPE-URL-QUERY QUERY) - escapes a query string in accordance
+with the HTTP specification.
Added: branches/trunk-reorg/thirdparty/trivial-https/trivial-https.asd
===================================================================
--- branches/trunk-reorg/thirdparty/trivial-https/trivial-https.asd 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/trivial-https/trivial-https.asd 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,13 @@
+;;;; Silly emacs, this is -*- Lisp -*- (or thereabouts)
+
+;;this is necessary due to a bug in SBCL
+#+sbcl
+(require :sb-bsd-sockets)
+
+(defsystem trivial-https
+ :name "trivial-https"
+ :author "Brian Mastenbrook/David Lichteblau"
+ :licence "MIT"
+ :description "Trivial support for HTTP GET and POST."
+ :depends-on (:trivial-sockets :cl+ssl)
+ :components ((:file "trivial-https")))
Added: branches/trunk-reorg/thirdparty/trivial-https/trivial-https.lisp
===================================================================
--- branches/trunk-reorg/thirdparty/trivial-https/trivial-https.lisp 2007-11-14 05:24:08 UTC (rev 2274)
+++ branches/trunk-reorg/thirdparty/trivial-https/trivial-https.lisp 2007-11-14 05:26:34 UTC (rev 2275)
@@ -0,0 +1,98 @@
+(defpackage :trivial-https
+ (:use :cl :trivial-sockets)
+ (:export :http-get :http-post :escape-url-query))
+(in-package :trivial-https)
+
+(defun url-scheme (url)
+ (assert (or (string-equal url "http://" :end1 7)
+ (string-equal url "https://" :end1 8)))
+ (subseq url 0 (position #\: url)))
+
+(defun url-port (url)
+ (let* ((scheme (url-scheme url))
+ (host-start (+ (length scheme) 3))
+ (path-start (position #\/ url :start host-start)))
+ (let ((port-start (position #\: url :start host-start :end path-start)))
+ (if port-start
+ (parse-integer url :start (1+ port-start) :junk-allowed t)
+ (if (equal scheme "https") 443 80)))))
+
+(defun url-host (url)
+ (let* ((host-start (+ (length (url-scheme url)) 3))
+ (port-start (position #\: url :start host-start))
+ (host-end (min (or (position #\/ url :start host-start) (length url))
+ (or port-start (length url)))))
+ (subseq url host-start host-end)))
+
+(defconstant +crlf+
+ (if (boundp '+crlf+)
+ (symbol-value '+crlf+)
+ (concatenate 'string
+ (string (code-char 13))
+ (string (code-char 10)))))
+
+(defun response-read-code (stream)
+ (let* ((l (read-line stream))
+ (space (position #\Space l)))
+ (parse-integer l :start (1+ space) :junk-allowed t)))
+
+(defun response-read-headers (stream)
+ (loop for line = (read-line stream nil nil)
+ until (or (eql (length line) 0)
+ (eql (elt line 0) (code-char 13))
+ (eql (elt line 0) (code-char 10)))
+ collect
+ (let ((colon (position #\: line)))
+ (cons (intern (string-upcase (subseq line 0 colon)) :keyword)
+ (string-trim (list #\Space (code-char 13) (code-char 10))
+ (subseq line (1+ colon)))))))
+
+(defun http-get (url &optional headers)
+ (let* ((host (url-host url))
+ (port (url-port url))
+ (stream
+ (if (equal (url-scheme url) "https")
+ (cl+ssl:make-ssl-client-stream
+ (open-stream host port :element-type '(unsigned-byte 8))
+ :external-format :iso-8859-1)
+ (open-stream host port))))
+ (format stream "GET ~A HTTP/1.0~AHost: ~A~AUser-Agent: Trivial HTTP for Common Lisp~A"
+ url +crlf+ host +crlf+ +crlf+)
+ (loop for (name . value) in headers do
+ (format stream "~A: ~A~A" name value +crlf+))
+ (write-string +crlf+ stream)
+ (force-output stream)
+ (list
+ (response-read-code stream)
+ (response-read-headers stream)
+ stream)))
+
+(defun http-post (url content-type content)
+ (let* ((host (url-host url))
+ (port (url-port url))
+ (stream
+ (if (equal (url-scheme url) "https")
+ (cl+ssl:make-ssl-client-stream
+ (open-stream host port :element-type '(unsigned-byte 8))
+ :external-format :iso-8859-1)
+ (open-stream host port))))
+ (format stream "POST ~A HTTP/1.0~AHost: ~A~AUser-Agent: Trivial HTTP for Common Lisp~AContent-Type: ~A~AContent-Length: ~D~A~A~A" url +crlf+ host +crlf+ +crlf+ content-type +crlf+ (length content) +crlf+ +crlf+ content)
+ (force-output stream)
+ (list
+ (response-read-code stream)
+ (response-read-headers stream)
+ stream)))
+
+;; this next method stolen from Araneida
+
+(defun url-reserved-character-p (c)
+ (not (or (member c '(#\- #\_ #\. #\! #\~ #\* #\' #\( #\) ))
+ (alphanumericp c))))
+
+(defun escape-url-query (query)
+ (apply #'concatenate 'string
+ (loop for c across query
+ if (url-reserved-character-p c)
+ collect (format nil "%~2,'0X" (char-code c))
+ else
+ collect (string c))))
1
0