Browse code
Add new generic extraction method
Ed Langley authored on 12/07/2019 09:19:42
Showing 2 changed files
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) |