index.html 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>CodeMirror: Common Lisp mode</title>
  6. <link rel="stylesheet" href="../../lib/codemirror.css">
  7. <script src="../../lib/codemirror.js"></script>
  8. <script src="commonlisp.js"></script>
  9. <style>.CodeMirror {background: #f8f8f8;}</style>
  10. <link rel="stylesheet" href="../../doc/docs.css">
  11. </head>
  12. <body>
  13. <h1>CodeMirror: Common Lisp mode</h1>
  14. <form><textarea id="code" name="code">(in-package :cl-postgres)
  15. ;; These are used to synthesize reader and writer names for integer
  16. ;; reading/writing functions when the amount of bytes and the
  17. ;; signedness is known. Both the macro that creates the functions and
  18. ;; some macros that use them create names this way.
  19. (eval-when (:compile-toplevel :load-toplevel :execute)
  20. (defun integer-reader-name (bytes signed)
  21. (intern (with-standard-io-syntax
  22. (format nil "~a~a~a~a" '#:read- (if signed "" '#:u) '#:int bytes))))
  23. (defun integer-writer-name (bytes signed)
  24. (intern (with-standard-io-syntax
  25. (format nil "~a~a~a~a" '#:write- (if signed "" '#:u) '#:int bytes)))))
  26. (defmacro integer-reader (bytes)
  27. "Create a function to read integers from a binary stream."
  28. (let ((bits (* bytes 8)))
  29. (labels ((return-form (signed)
  30. (if signed
  31. `(if (logbitp ,(1- bits) result)
  32. (dpb result (byte ,(1- bits) 0) -1)
  33. result)
  34. `result))
  35. (generate-reader (signed)
  36. `(defun ,(integer-reader-name bytes signed) (socket)
  37. (declare (type stream socket)
  38. #.*optimize*)
  39. ,(if (= bytes 1)
  40. `(let ((result (the (unsigned-byte 8) (read-byte socket))))
  41. (declare (type (unsigned-byte 8) result))
  42. ,(return-form signed))
  43. `(let ((result 0))
  44. (declare (type (unsigned-byte ,bits) result))
  45. ,@(loop :for byte :from (1- bytes) :downto 0
  46. :collect `(setf (ldb (byte 8 ,(* 8 byte)) result)
  47. (the (unsigned-byte 8) (read-byte socket))))
  48. ,(return-form signed))))))
  49. `(progn
  50. ;; This causes weird errors on SBCL in some circumstances. Disabled for now.
  51. ;; (declaim (inline ,(integer-reader-name bytes t)
  52. ;; ,(integer-reader-name bytes nil)))
  53. (declaim (ftype (function (t) (signed-byte ,bits))
  54. ,(integer-reader-name bytes t)))
  55. ,(generate-reader t)
  56. (declaim (ftype (function (t) (unsigned-byte ,bits))
  57. ,(integer-reader-name bytes nil)))
  58. ,(generate-reader nil)))))
  59. (defmacro integer-writer (bytes)
  60. "Create a function to write integers to a binary stream."
  61. (let ((bits (* 8 bytes)))
  62. `(progn
  63. (declaim (inline ,(integer-writer-name bytes t)
  64. ,(integer-writer-name bytes nil)))
  65. (defun ,(integer-writer-name bytes nil) (socket value)
  66. (declare (type stream socket)
  67. (type (unsigned-byte ,bits) value)
  68. #.*optimize*)
  69. ,@(if (= bytes 1)
  70. `((write-byte value socket))
  71. (loop :for byte :from (1- bytes) :downto 0
  72. :collect `(write-byte (ldb (byte 8 ,(* byte 8)) value)
  73. socket)))
  74. (values))
  75. (defun ,(integer-writer-name bytes t) (socket value)
  76. (declare (type stream socket)
  77. (type (signed-byte ,bits) value)
  78. #.*optimize*)
  79. ,@(if (= bytes 1)
  80. `((write-byte (ldb (byte 8 0) value) socket))
  81. (loop :for byte :from (1- bytes) :downto 0
  82. :collect `(write-byte (ldb (byte 8 ,(* byte 8)) value)
  83. socket)))
  84. (values)))))
  85. ;; All the instances of the above that we need.
  86. (integer-reader 1)
  87. (integer-reader 2)
  88. (integer-reader 4)
  89. (integer-reader 8)
  90. (integer-writer 1)
  91. (integer-writer 2)
  92. (integer-writer 4)
  93. (defun write-bytes (socket bytes)
  94. "Write a byte-array to a stream."
  95. (declare (type stream socket)
  96. (type (simple-array (unsigned-byte 8)) bytes)
  97. #.*optimize*)
  98. (write-sequence bytes socket))
  99. (defun write-str (socket string)
  100. "Write a null-terminated string to a stream \(encoding it when UTF-8
  101. support is enabled.)."
  102. (declare (type stream socket)
  103. (type string string)
  104. #.*optimize*)
  105. (enc-write-string string socket)
  106. (write-uint1 socket 0))
  107. (declaim (ftype (function (t unsigned-byte)
  108. (simple-array (unsigned-byte 8) (*)))
  109. read-bytes))
  110. (defun read-bytes (socket length)
  111. "Read a byte array of the given length from a stream."
  112. (declare (type stream socket)
  113. (type fixnum length)
  114. #.*optimize*)
  115. (let ((result (make-array length :element-type '(unsigned-byte 8))))
  116. (read-sequence result socket)
  117. result))
  118. (declaim (ftype (function (t) string) read-str))
  119. (defun read-str (socket)
  120. "Read a null-terminated string from a stream. Takes care of encoding
  121. when UTF-8 support is enabled."
  122. (declare (type stream socket)
  123. #.*optimize*)
  124. (enc-read-string socket :null-terminated t))
  125. (defun skip-bytes (socket length)
  126. "Skip a given number of bytes in a binary stream."
  127. (declare (type stream socket)
  128. (type (unsigned-byte 32) length)
  129. #.*optimize*)
  130. (dotimes (i length)
  131. (read-byte socket)))
  132. (defun skip-str (socket)
  133. "Skip a null-terminated string."
  134. (declare (type stream socket)
  135. #.*optimize*)
  136. (loop :for char :of-type fixnum = (read-byte socket)
  137. :until (zerop char)))
  138. (defun ensure-socket-is-closed (socket &amp;key abort)
  139. (when (open-stream-p socket)
  140. (handler-case
  141. (close socket :abort abort)
  142. (error (error)
  143. (warn "Ignoring the error which happened while trying to close PostgreSQL socket: ~A" error)))))
  144. </textarea></form>
  145. <script>
  146. var editor = CodeMirror.fromTextArea(document.getElementById("code"), {lineNumbers: true});
  147. </script>
  148. <p><strong>MIME types defined:</strong> <code>text/x-common-lisp</code>.</p>
  149. </body>
  150. </html>