From 4d82ef18a8bb18317be3e089f432f95b6e5dbd4a Mon Sep 17 00:00:00 2001 From: Piotr Szarmanski Date: Thu, 22 Sep 2022 11:16:44 +0200 Subject: Implement stream-read-byte --- src/eris-decode.lisp | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'src/eris-decode.lisp') diff --git a/src/eris-decode.lisp b/src/eris-decode.lisp index b7575ab..43f8db0 100644 --- a/src/eris-decode.lisp +++ b/src/eris-decode.lisp @@ -186,7 +186,7 @@ fetched from a trusted party.") (setf (pos stream) new-pos (data buffer) (data (car (last root))) (pos buffer) (mod new-pos block-size)) - (if (= (- eof (mod eof block-size)) new-pos) + (if (< (- eof (mod eof block-size)) new-pos) (unpad-buffer buffer) (setf (eof buffer) block-size)))))) @@ -199,23 +199,25 @@ fetched from a trusted party.") (defun eris-decode (read-capability fetch-function &key (cache-capacity 2048)) - "With a given fetch-function, return a stream that decodes the read-capability. + "Using the FETCH-FUNCTION, return a stream that decodes the READ-CAPABILITY. Fetch-function must be a function with one argument, the reference octet, which returns a (simple-array (unsigned-byte 8)) containing the block. The block will be destructively modified, so you MUST provide a fresh array every time. If a hash-table is used, a (copy-seq) needs to be done on the return value of -gethash. " +gethash. + +The keyword argument CACHE-CAPACITY indicates the amount of blocks stored in the +cache." (with-slots (level block-size root-reference-pair) read-capability (let* ((get-block (cached-lambda (:cache-class 'lru-cache :capacity cache-capacity :table (make-hash-table :size (1+ cache-capacity) :test #'equalp)) (reference key &optional nonce) (let* ((block (funcall fetch-function reference))) + (unless block (error 'missing-block :reference reference)) (hash-check block reference) - (if block - (decrypt-block block key nonce) - (error 'missing-block :reference reference))))) + (decrypt-block block key nonce)))) (root (funcall get-block (reference root-reference-pair) (key root-reference-pair) (make-nonce level)))) ;; "Implementations MUST verify the key appearing in the read capability ;; if level of encoded content is larger than 0." @@ -282,10 +284,25 @@ the new position is beyond the end of file.." (read-to-seq seq buffer :start start :end (if end end (length seq)) :stream stream))) (defmethod stream-read-byte ((stream eris-decode-stream)) - nil) + (when (minusp (pos (buffer stream))) + ;; initializes the buffer + (reupdate-block stream (pos stream))) + (with-slots (position buffer block-size) stream + (with-slots (pos eof data) buffer + (cond + ((eql pos block-size) + (setf pos 0) + (advance-next-block stream) + (stream-read-byte stream)) + ((eql pos eof) + :eof) + (t (prog1 (aref data pos) + (incf pos) + (incf position))))))) (defmethod stream-element-type ((stream eris-decode-stream)) '(unsigned-byte 8)) (defun eris-file-length (stream) + "This is the equivalent of \"file-length\" for eris-decode-stream." (eof stream)) -- cgit v1.2.3