git.fiddlerwoaroof.com
Browse code

Add new generic extraction method

Ed Langley authored on 12/07/2019 09:19:42
Showing 2 changed files
... ...
@@ -115,9 +115,28 @@
115 115
           (file-position p object-offset-in-pack)
116 116
           (read-object-from-pack p (repository pack)))))))
117 117
 
118
-(defun extract-loose-object (repo id)
119
-  (with-open-file (s (loose-object repo id)
120
-                     :element-type '(unsigned-byte 8))
118
+(defclass git-object ()
119
+  ((%repo :initarg :repo :reader object-repo)
120
+   (%hash :initarg :hash :reader object-hash)))
121
+(defclass loose-object (git-object)
122
+  ((%file :initarg :file :reader loose-object-file)))
123
+(defclass packed-object (git-object)
124
+  ((%pack :initarg :pack :reader packed-object-pack)
125
+   (%offset :initarg :offset :reader packed-object-offset)))
126
+
127
+(defun object (repo id)
128
+  (let ((repo-root (typecase repo
129
+                     (repository (root repo))
130
+                     (string (namestring
131
+                              (truename repo))))))
132
+    (or (alexandria:when-let ((object-file (loose-object repo id)))
133
+          (make-instance 'loose-object :repo repo-root :hash id :file object-file))
134
+        (multiple-value-bind (pack offset) (find-object-in-pack-files repo id)
135
+          (when pack
136
+            (make-instance 'packed-object :repo repo-root :offset offset :pack pack))))))
137
+
138
+(defun extract-loose-object (repo file)
139
+  (with-open-file (s file :element-type '(unsigned-byte 8))
121 140
     (alexandria:when-let ((result (chipz:decompress nil (chipz:make-dstate 'chipz:zlib)
122 141
                                                     s)))
123 142
       (destructuring-bind (type rest)
... ...
@@ -127,9 +146,18 @@
127 146
                                      1)
128 147
                                 repo)))))
129 148
 
149
+(defgeneric extract-object-next (object)
150
+  (:method ((object loose-object))
151
+    (extract-loose-object (object-repo object)
152
+                          (loose-object-file object)))
153
+  (:method ((object packed-object))
154
+    (data-lens.lenses:view *object-data-lens*
155
+                           (extract-object-from-pack (packed-object-pack object)
156
+                                                     (packed-object-offset object)))))
157
+
130 158
 (defun extract-object (repo id)
131 159
   (if (loose-object-p repo id)
132
-      (extract-loose-object repo id)
160
+      (extract-loose-object repo (loose-object repo id))
133 161
       (data-lens.lenses:view *object-data-lens*
134 162
                              (multiple-value-call 'extract-object-from-pack 
135 163
                                (find-object-in-pack-files (root repo) id)))))
... ...
@@ -7,14 +7,25 @@
7 7
     (let ((object-offset-in-pack (read-bytes 4 'fwoar.bin-parser:be->int idx-stream)))
8 8
       (file-position pack-stream object-offset-in-pack))))
9 9
 
10
+(deftype octet ()
11
+  '(unsigned-byte 8))
12
+
13
+(defmacro with-open-files* ((&rest bindings) &body body)
14
+  `(uiop:nest ,@(mapcar (serapeum:op
15
+                          `(with-open-file ,_1))
16
+                        bindings)
17
+              (progn
18
+                ,@body)))
19
+
10 20
 (defun extract-object-metadata-from-pack (pack obj-number)
11
-  (with-open-file (s (index-file pack) :element-type '(unsigned-byte 8))
12
-    (with-open-file (p (pack-file pack) :element-type '(unsigned-byte 8))
13
-      (seek-to-object-in-pack s p obj-number)
14
-      (read-object-metadata-from-pack p))))
21
+  (with-open-files* ((s (index-file pack) :element-type 'octet)
22
+                     (p (pack-file pack) :element-type 'octet))
23
+    (seek-to-object-in-pack s p obj-number)
24
+    (read-object-metadata-from-pack p)))
15 25
 
16 26
 (defun turn-read-object-to-string (object)
17
-  (data-lens.lenses:over *object-data-lens* 'babel:octets-to-string object))
27
+  (data-lens.lenses:over *object-data-lens*
28
+                         'babel:octets-to-string object))
18 29
 
19 30
 (defgeneric loose-object (repository id)
20 31
   (:method ((repository string) id)