source: branches/home/psmith/restructure/src/buffer/buffer.lisp @ 27

Last change on this file since 27 was 27, checked in by psmith, 18 years ago

Added first steps of YetAnotherRPC protocol

File size: 6.3 KB
Line 
1#|
2Copyright (c) 2006 Risto Laakso
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions
7are met:
81. Redistributions of source code must retain the above copyright
9   notice, this list of conditions and the following disclaimer.
102. Redistributions in binary form must reproduce the above copyright
11   notice, this list of conditions and the following disclaimer in the
12   documentation and/or other materials provided with the distribution.
133. The name of the author may not be used to endorse or promote products
14   derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26|#
27
28(in-package :nio-buffer)
29
30
31;;NIO-buffers - to simplify operations on buffers.
32;;
33;; Will support direct(external to the vm) and non-direct buffers
34;;
35
36(declaim (optimize (debug 3) (speed 3) (space 0)))
37
38
39(defclass buffer ()
40  ((capacity     :initarg :capacity
41                 :initform 0
42                 :accessor buffer-capacity
43                 :documentation "Buffer capacity")
44   (limit        :initarg :limit
45                 :initform 0
46                 :accessor buffer-limit
47                 :documentation "Index of first element the should *not* be read or written 0 <= limit <= capacity")
48   (position     :initarg :position
49                 :initform 0
50                 :accessor buffer-position
51                 :documentation "Index of next element to be read/written 0<=position<=limit")
52   (buf          :initarg :buf
53                 :accessor buffer-buf)))
54
55
56;;Utils by slyrus (http://paste.lisp.org/display/11149)
57(defun hex-dump-byte (address)
58  (format nil "~2,'0X"
59          (sb-alien:deref
60           (sb-alien:sap-alien
61            (sb-alien::int-sap address)
62            (* (sb-alien:unsigned 8))))))
63
64(defun hex-dump-memory (start-address length)
65  (loop for i from start-address below (+ start-address length)
66     collect (format nil (hex-dump-byte i))))
67
68
69(defun make-uint8-seq (size)
70  "Make uint8 sequence."
71  (make-sequence '(vector (unsigned-byte 8)) size :initial-element 0))
72
73
74;;-- end utils
75
76
77;;A buffer that deals with bytes
78(defclass byte-buffer (buffer)())
79
80(defun byte-buffer (capacity)
81  (make-instance 'byte-buffer :capacity capacity :limit capacity :position 0 :buf (foreign-alloc :uint8 :count capacity)))
82
83
84(defmethod print-object ((byte-buffer byte-buffer) stream)
85  (with-slots (capacity position limit buf) byte-buffer
86    (format stream "<byte-buffer :capacity ~A :position ~A :limit ~A :buf ~%~A>~%" capacity position limit (if buf (hex-dump-memory (pointer-address buf) limit) nil))))
87
88(defmethod free-buffer((byte-buffer byte-buffer))
89  (with-slots (capacity position limit buf) byte-buffer
90    (foreign-free buf)
91    (setf buf NIL)
92    (setf capacity 0)
93    (setf limit 0)
94    (setf position 0)))
95
96
97(defmethod remaining((byte-buffer byte-buffer))
98  (with-slots (position limit) byte-buffer
99    (- limit position)))
100
101
102(defmethod inc-position((byte-buffer byte-buffer) num-bytes)
103  (with-slots (position limit) byte-buffer
104    (let ((new-pos (+ position num-bytes)))
105      (assert (<= new-pos limit))
106      (setf position new-pos))))
107
108(defmethod flip((byte-buffer byte-buffer))
109  :documentation "make buffer ready for relative get operation"
110  (with-slots (position limit) byte-buffer
111    (setf limit position)
112    (setf position 0)))
113
114(defmethod clear((byte-buffer byte-buffer))
115  :documentation "Reset the position to 0 and the limit to capacity"
116  (with-slots (position limit capacity) byte-buffer
117    (setf limit capacity)
118    (setf position 0)
119    byte-buffer))
120
121
122(defmethod get-string((byte-buffer byte-buffer))
123  (flip byte-buffer)
124  (with-slots (position limit buf) byte-buffer
125    (let ((tmp  (make-uint8-seq (remaining byte-buffer))))
126      (inc-position byte-buffer (cffi:mem-read-vector tmp buf :unsigned-char limit))
127      (format t " read: ~A~%" (sb-ext:octets-to-string tmp :external-format :ascii))
128      tmp)))
129   
130;;TODO
131;;mem-write-vector (vector ptr type &optional (count (length vector)) (offset 0))
132(defmethod bytebuffer-write-string((byte-buffer byte-buffer) str &optional (index 0) (external-format :ascii))
133  :documentation "Returns number of bytes written to bytebuffer"
134  (bytebuffer-write-vector byte-buffer (sb-ext:string-to-octets str :external-format external-format)))
135
136;;TODO rename
137(defmethod bytebuffer-write-vector((byte-buffer byte-buffer) vec &optional (index 0))
138  :documentation "Returns number of bytes written to bytebuffer"
139  (if (> (remaining byte-buffer) 0)
140      0
141      (progn   
142        (clear byte-buffer)
143        (let ((bytes-written (mem-write-vector vec (buffer-buf byte-buffer) :unsigned-char)))
144          (format t "bytebuffer-write-vector -  byteswritten: ~A" bytes-written)
145          (inc-position byte-buffer bytes-written)
146          bytes-written))))
147
148
149(defmethod map-to-foreign ((byte-buffer byte-buffer) seq &optional (start 0) (end (length seq)))
150  "Map SEQ to foreign array."
151  (clear byte-buffer)
152  (let* ((len (- end start)))
153    (loop for i from 0 below len do
154         (setf (mem-aref (buffer-buf byte-buffer) :uint8 i) (aref seq (+ start i)))))
155  (inc-position byte-buffer end))
156
157
158
159(defcfun ("memset" %memset) :pointer
160  (buffer :pointer)
161  (byte :int)
162  (len :int))
163
164(defun test-buffer()
165  (let ((mybuf (byte-buffer 32)))
166    (format t "Mybuf: ~A~%" mybuf)
167    (assert (eql 32 (remaining mybuf)))
168    (inc-position mybuf 2)
169    (assert (eql 30 (remaining mybuf)))
170    (format t "Mybuf: ~A~%" mybuf)
171
172 (%memset (buffer-buf mybuf) 78 4)
173
174    (format t "Mybuf (after memset): ~A~%" mybuf)
175;    (flip mybuf)
176;    (format t "Mybuf (after flip): ~A~%" mybuf)
177
178
179    (format t "Remaining ~A~%" (remaining mybuf))
180
181    (format t "mybuf string ~A~%" (get-string mybuf))
182
183    (format t "Mybuf (after get-string): ~A~%" mybuf)
184
185    (format t "Mybuf (after clear): ~A~%" (clear mybuf))
186
187    (free-buffer mybuf)
188    (format t "Mybuf after free: ~A~%" mybuf)))
189
Note: See TracBrowser for help on using the repository browser.