[Libreoffice-commits] libvisio.git: src/lib

Miklos Vajna vmiklos at collabora.co.uk
Tue Dec 2 07:55:03 PST 2014


 src/lib/VSDMetaData.cpp |   53 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/lib/VSDMetaData.h   |    1 
 src/lib/VSDParser.cpp   |    2 +
 3 files changed, 56 insertions(+)

New commits:
commit 02c96626a14e7435e38a142397640926978deb5e
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Dec 2 16:46:44 2014 +0100

    fdo#86664 VSD: import Creation/ModifiedTime
    
    Change-Id: Ia1287ef49fa5225ab9bb5effa65d8b61e4015f8d

diff --git a/src/lib/VSDMetaData.cpp b/src/lib/VSDMetaData.cpp
index 209cc34..3fd5bf9 100644
--- a/src/lib/VSDMetaData.cpp
+++ b/src/lib/VSDMetaData.cpp
@@ -8,6 +8,7 @@
  */
 
 #include "VSDMetaData.h"
+#include <cmath>
 #include <unicode/ucnv.h>
 
 libvisio::VSDMetaData::VSDMetaData()
@@ -172,6 +173,58 @@ librevenge::RVNGString libvisio::VSDMetaData::readCodePageString(librevenge::RVN
   return string;
 }
 
+bool libvisio::VSDMetaData::parseTimes(librevenge::RVNGInputStream *input)
+{
+  // Parse the header
+  // HeaderSignature: 8 bytes
+  // HeaderCLSID: 16 bytes
+  // MinorVersion: 2 bytes
+  // MajorVersion: 2 bytes
+  // ByteOrder: 2 bytes
+  input->seek(30, librevenge::RVNG_SEEK_CUR);
+  uint16_t sectorShift = readU16(input);
+  // MiniSectorShift: 2 bytes
+  // Reserved: 6 bytes
+  // NumDirectorySectors: 4 bytes
+  // NumFATSectors: 4 bytes
+  input->seek(16, librevenge::RVNG_SEEK_CUR);
+  uint32_t firstDirSectorLocation = readU32(input);
+
+  // Seek to the Root Directory Entry
+  size_t sectorSize = pow(2, sectorShift);
+  input->seek((firstDirSectorLocation + 1) * sectorSize, librevenge::RVNG_SEEK_SET);
+  // DirectoryEntryName: 64 bytes
+  // DirectoryEntryNameLength: 2 bytes
+  // ObjectType: 1 byte
+  // ColorFlag: 1 byte
+  // LeftSiblingID: 4 bytes
+  // RightSiblingID: 4 bytes
+  // ChildID: 4 bytes
+  // CLSID: 16 bytes
+  // StateBits: 4 bytes
+  // CreationTime: 8 bytes
+  input->seek(108, librevenge::RVNG_SEEK_CUR);
+  uint64_t modifiedTime = readU64(input);
+
+  // modifiedTime is number of 100ns since Jan 1 1601
+  static const uint64_t epoch = 11644473600;
+  time_t sec = (modifiedTime / 10000000) - epoch;
+  const struct tm *time = localtime(&sec);
+  if (time)
+  {
+    static const int MAX_BUFFER = 1024;
+    char buffer[MAX_BUFFER];
+    strftime(&buffer[0], MAX_BUFFER-1, "%Y-%m-%dT%H:%M:%SZ", time);
+    librevenge::RVNGString result;
+    result.append(buffer);
+    // Visio UI uses modifiedTime for both purposes.
+    m_metaData.insert("meta:creation-date", result);
+    m_metaData.insert("dc:date", result);
+    return true;
+  }
+  return false;
+}
+
 const librevenge::RVNGPropertyList &libvisio::VSDMetaData::getMetaData()
 {
   return m_metaData;
diff --git a/src/lib/VSDMetaData.h b/src/lib/VSDMetaData.h
index c185894..581b0a2 100644
--- a/src/lib/VSDMetaData.h
+++ b/src/lib/VSDMetaData.h
@@ -26,6 +26,7 @@ public:
   VSDMetaData();
   ~VSDMetaData();
   bool parse(librevenge::RVNGInputStream *input);
+  bool parseTimes(librevenge::RVNGInputStream *input);
   const librevenge::RVNGPropertyList &getMetaData();
 
 private:
diff --git a/src/lib/VSDParser.cpp b/src/lib/VSDParser.cpp
index b69e5fd..65702b4 100644
--- a/src/lib/VSDParser.cpp
+++ b/src/lib/VSDParser.cpp
@@ -163,6 +163,8 @@ bool libvisio::VSDParser::parseMetaData()
 
   VSDMetaData metaData;
   metaData.parse(stream);
+  m_container->seek(0, librevenge::RVNG_SEEK_SET);
+  metaData.parseTimes(m_container);
   m_collector->collectMetaData(metaData.getMetaData());
 
   delete stream;


More information about the Libreoffice-commits mailing list