commit 6d8daadaf1067381b20503f30e53260136b1d236
parent c99dc99676e4e1b9c03b5be723437dc6ef28ded8
Author: Tomas Hlavaty <tom@logand.com>
Date: Wed, 13 Jul 2011 00:55:29 +0200
compute live persist object directory and DocumentContainer
Diffstat:
M | olefs.lisp | | | 114 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
1 file changed, 58 insertions(+), 56 deletions(-)
diff --git a/olefs.lisp b/olefs.lisp
@@ -444,17 +444,15 @@
(filter ubyte :always #xfe))
(define-structure PersistDirectoryEntry ()
- ;; (%dummy1 ubyte)
- ;; (%dummy2 ubyte)
- ;; (%dummy3 ubyte)
- ;; (%dummy4 ubyte)
(%dummy dword)
- (persistId t :compute (ash %dummy -12))
- (cPersist t :compute (logand #x0fff %dummy))
+ (persistId t :compute (logand #xfffff %dummy))
+ (cPersist t :compute (ash %dummy -20))
(rgPersistOffset (dword cPersist)))
(defstruct blip header ext guid guid2 metafileHeader)
+(defstruct PersistDirectoryAtom header entries)
+
(defun read-record-body (stream RecordHeader &optional fn)
(let ((x RecordHeader #+nil(read-RecordHeader stream)))
(with-slots (recVer recInstance recType recLen) x
@@ -489,20 +487,20 @@
(assert (zerop recInstance))
(with-shorter-stream (in stream (RecordHeader.recLen x))
(list x (read-UserEditAtom in))))
- (#.RT_PersistDirectoryAtom ;; TODO
+ (#.RT_PersistDirectoryAtom
(assert (zerop recVer))
(assert (zerop recInstance))
- (print (RecordHeader.recLen x))
- (with-shorter-stream (in stream (RecordHeader.recLen x))
- (list x
- (read-PersistDirectoryEntry in)
- #+nil
- (loop
- for fpos = 0 then (file-position in)
- while (< fpos (RecordHeader.recLen x))
- collect (progn
- (print fpos)
- (read-PersistDirectoryEntry in))))))
+ (let ((n (RecordHeader.recLen x)))
+ ;;(print n)
+ (with-shorter-stream (in stream n)
+ (make-PersistDirectoryAtom
+ :header x
+ :entries (loop
+ for fpos = 0 then (file-position in)
+ while (< fpos n)
+ collect (progn
+ ;;(print fpos)
+ (read-PersistDirectoryEntry in)))))))
#+nil
(#.RT_Document ;; TODO
)
@@ -849,24 +847,16 @@
(out "</div>~%</body>~%</html>~%"))))
(defun process-PersistDirectoryAtom (htab in)
- (let ((d (cadr (read-record in))))
- (with-slots (persistId cPersist rgPersistOffset) d
+ (dolist (entry (PersistDirectoryAtom-entries (read-record in)))
+ (with-slots (persistId cPersist rgPersistOffset) entry
(loop
for n from 0
for o across rgPersistOffset
do (let ((k (+ persistId n)))
- (print (list k :-> o))
- (setf (gethash k htab) o)))))
- #+nil
- (loop
- for d = (cadr (read-record in)) ;;then (cadr (read-record in))
- do (with-slots (persistId cPersist rgPersistOffset) d
- (loop
- for n from 0
- for o across rgPersistOffset
- do (let ((k (+ persistId n)))
- (print (list k :-> o))
- (setf (gethash k htab) o))))))
+ ;;(print (list :??? persistId :+ n := k :-> o))
+ (unless (gethash k htab)
+ ;;(print (list persistId :+ n := k :-> o))
+ (setf (gethash k htab) o)))))))
(defun ppt-file-to-html (filename &optional (stream *standard-output*))
(with-ole-file (ole-file filename)
@@ -888,27 +878,39 @@
(declare (ignore level i start end parents))
(return-from CurrentUser
(cadr (read-record-body in h))))))))))))))
- (describe u)
- (traverse-directories
- ole-file
- (lambda (entry id level)
- (declare (ignore id level))
- (case (ole-entry.object-type entry)
- (2 ;; stream
- (let ((entry-name (ole-entry-name-to-string
- (ole-entry.name entry)
- (ole-entry.name-length entry))))
- (when (equal "PowerPoint Document" entry-name)
- (with-ole-entry-stream (in ole-file entry)
- (let ((htab (make-hash-table))) ;; persist oid -> fpos
- (file-position in (CurrentUserAtom.offsetToCurrentEdit u))
- (loop
- for e = (cadr (read-record in)) then (cadr (read-record in))
- do (progn
- (describe e)
- (file-position in (UserEditAtom.offsetPersistDirectory e))
- (process-PersistDirectoryAtom htab in))
- until (zerop (UserEditAtom.offsetLastEdit e))
- do (file-position in (UserEditAtom.offsetLastEdit e))))
- #+nil(file-position in 0)
- #+nil(print (read-record in))))))))))))
+ ;;(describe u)
+ (let ((pictures nil))
+ ;;(extract-pictures ole-file dir html) ;; TODO mount olefs and traverse Pictures only once
+ (walk-RecordHeader-tree ole-file
+ (find-ole-entry ole-file "Pictures")
+ (lambda (in level i h start end parents)
+ (declare (ignore level end parents))
+ (multiple-value-bind (blip kind)
+ (read-record-body in h)
+ (declare (ignore blip))
+ (push (list i (- start 8) kind) pictures))))
+ (print (list :pictures pictures))
+ (with-ole-entry-stream (in ole-file
+ (find-ole-entry ole-file "PowerPoint Document"))
+ (let ((htab (make-hash-table)) ;; persist oid -> fpos
+ (first-UserEditAtom nil))
+ (file-position in (CurrentUserAtom.offsetToCurrentEdit u))
+ (loop
+ for e = (cadr (read-record in)) then (cadr (read-record in))
+ do (progn
+ ;;(describe e)
+ (unless first-UserEditAtom
+ (setq first-UserEditAtom e))
+ (file-position in (UserEditAtom.offsetPersistDirectory e))
+ (process-PersistDirectoryAtom htab in))
+ until (zerop (UserEditAtom.offsetLastEdit e))
+ do (file-position in (UserEditAtom.offsetLastEdit e)))
+ ;; live PersistDirectory
+ (let ((persist-directory nil))
+ (maphash (lambda (k v) (push (cons k v) persist-directory)) htab)
+ (setq persist-directory (sort persist-directory #'< :key #'car))
+ (print persist-directory))
+ ;; live DocumentContainer
+ (print (gethash (UserEditAtom.docPersistIdRef first-UserEditAtom) htab)))
+ #+nil(file-position in 0)
+ #+nil(print (read-record in)))))))