[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - external/libvisio

Miklos Vajna vmiklos at collabora.co.uk
Tue Dec 2 10:12:54 PST 2014


 external/libvisio/UnpackedTarball_libvisio.mk |    1 
 external/libvisio/vsd-metadata.patch.1        |  651 ++++++++++++++++++++++++++
 2 files changed, 652 insertions(+)

New commits:
commit 5d863d458dbf0ba581f550b2e82788878c1e5b31
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Dec 2 17:09:30 2014 +0100

    fdo#86664 VSD import: handle metadata
    
    (cherry picked from commit 9b61cf4a70b9c3023d035a1b0f7cc1488dd55e22)
    (cherry picked from commit 386014bb5ee1fb611bbc00c37c04cdf191a833b7)
    
    Change-Id: Icec212a93df10b212a9ae614b5c1ced6bf25ff7f

diff --git a/external/libvisio/UnpackedTarball_libvisio.mk b/external/libvisio/UnpackedTarball_libvisio.mk
index 4451eb5..dddf0b7 100644
--- a/external/libvisio/UnpackedTarball_libvisio.mk
+++ b/external/libvisio/UnpackedTarball_libvisio.mk
@@ -14,6 +14,7 @@ $(eval $(call gb_UnpackedTarball_set_tarball,libvisio,$(VISIO_TARBALL)))
 $(eval $(call gb_UnpackedTarball_add_patches,libvisio,\
 	external/libvisio/libvisio_quote.patch.1 \
 	external/libvisio/vsdx-metadata.patch.1 \
+	external/libvisio/vsd-metadata.patch.1 \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/external/libvisio/vsd-metadata.patch.1 b/external/libvisio/vsd-metadata.patch.1
new file mode 100644
index 0000000..1704bad
--- /dev/null
+++ b/external/libvisio/vsd-metadata.patch.1
@@ -0,0 +1,651 @@
+commit a7f7ccbd4089965511dc59c3ae7869b360c8ca9f
+Author: Miklos Vajna <vmiklos at collabora.co.uk>
+Date:   Tue Dec 2 17:05:23 2014 +0100
+
+    Move _appendUCS4() to libvisio_utils
+
+diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp
+index 822a5f4..083fd91 100644
+--- a/src/lib/VSDContentCollector.cpp
++++ b/src/lib/VSDContentCollector.cpp
+@@ -11,7 +11,6 @@
+ #include <stack>
+ #include <boost/spirit/include/classic.hpp>
+ #include <unicode/ucnv.h>
+-#include <unicode/utypes.h>
+ #include <unicode/utf8.h>
+ 
+ #include "VSDContentCollector.h"
+@@ -33,27 +32,6 @@ static unsigned bitmapId = 0;
+ 
+ #define SURROGATE_VALUE(h,l) (((h) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000)
+ 
+-namespace
+-{
+-
+-static void _appendUCS4(librevenge::RVNGString &text, UChar32 ucs4Character)
+-{
+-  // Convert carriage returns to new line characters
+-  // Writerperfect/LibreOffice will replace them by <text:line-break>
+-  if (ucs4Character == (UChar32) 0x0d || ucs4Character == (UChar32) 0x0e)
+-    ucs4Character = (UChar32) '\n';
+-
+-  unsigned char outbuf[U8_MAX_LENGTH+1];
+-  int i = 0;
+-  U8_APPEND_UNSAFE(&outbuf[0], i, ucs4Character);
+-  outbuf[i] = 0;
+-
+-  text.append((char *)outbuf);
+-}
+-
+-} // anonymous namespace
+-
+-
+ libvisio::VSDContentCollector::VSDContentCollector(
+   librevenge::RVNGDrawingInterface *painter,
+   std::vector<std::map<unsigned, XForm> > &groupXFormsSequence,
+@@ -2870,7 +2848,7 @@ void libvisio::VSDContentCollector::appendCharacters(librevenge::RVNGString &tex
+         ucs4Character = 0x20;
+       else
+         ucs4Character = symbolmap[*iter - 0x20];
+-      _appendUCS4(text, ucs4Character);
++      appendUCS4(text, ucs4Character);
+     }
+   }
+   else
+@@ -2934,7 +2912,7 @@ void libvisio::VSDContentCollector::appendCharacters(librevenge::RVNGString &tex
+           if (0x1e == ucs4Character)
+             _appendField(text);
+           else
+-            _appendUCS4(text, ucs4Character);
++            appendUCS4(text, ucs4Character);
+         }
+       }
+     }
+@@ -2960,7 +2938,7 @@ void libvisio::VSDContentCollector::appendCharacters(librevenge::RVNGString &tex
+         if (0xfffc == ucs4Character)
+           _appendField(text);
+         else
+-          _appendUCS4(text, ucs4Character);
++          appendUCS4(text, ucs4Character);
+       }
+     }
+   }
+diff --git a/src/lib/libvisio_utils.cpp b/src/lib/libvisio_utils.cpp
+index b137e24..e622417 100644
+--- a/src/lib/libvisio_utils.cpp
++++ b/src/lib/libvisio_utils.cpp
+@@ -107,6 +107,20 @@ const librevenge::RVNGString libvisio::getColourString(const Colour &c)
+   return sColour;
+ }
+ 
++void libvisio::appendUCS4(librevenge::RVNGString &text, UChar32 ucs4Character)
++{
++  // Convert carriage returns to new line characters
++  // Writerperfect/LibreOffice will replace them by <text:line-break>
++  if (ucs4Character == (UChar32) 0x0d || ucs4Character == (UChar32) 0x0e)
++    ucs4Character = (UChar32) '\n';
++
++  unsigned char outbuf[U8_MAX_LENGTH+1];
++  int i = 0;
++  U8_APPEND_UNSAFE(&outbuf[0], i, ucs4Character);
++  outbuf[i] = 0;
++
++  text.append((char *)outbuf);
++}
+ 
+ 
+ /* vim:set shiftwidth=2 softtabstop=2 expandtab: */
+diff --git a/src/lib/libvisio_utils.h b/src/lib/libvisio_utils.h
+index 08ebb04..60be13f 100644
+--- a/src/lib/libvisio_utils.h
++++ b/src/lib/libvisio_utils.h
+@@ -47,6 +47,7 @@ typedef unsigned __int64 uint64_t;
+ 
+ #include <librevenge/librevenge.h>
+ #include <librevenge-stream/librevenge-stream.h>
++#include <unicode/utypes.h>
+ 
+ // debug message includes source file and line number
+ //#define VERBOSE_DEBUG 1
+@@ -79,6 +80,8 @@ double readDouble(librevenge::RVNGInputStream *input);
+ 
+ const librevenge::RVNGString getColourString(const Colour &c);
+ 
++void appendUCS4(librevenge::RVNGString &text, UChar32 ucs4Character);
++
+ class EndOfStreamException
+ {
+ };
+commit 005b45ddf64a8320a0143336d431a016507d2085
+Author: Miklos Vajna <vmiklos at collabora.co.uk>
+Date:   Tue Dec 2 17:01:35 2014 +0100
+
+    fdo#86729 VSD: import metadata
+    
+    Only title as a start.
+
+diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
+index 955aac4..f4d86fa 100644
+--- a/src/lib/Makefile.am
++++ b/src/lib/Makefile.am
+@@ -39,6 +39,7 @@ libvisio_ at VSD_MAJOR_VERSION@_ at VSD_MINOR_VERSION@_la_SOURCES = \
+ 	VSDPages.cpp \
+ 	VSDParagraphList.cpp \
+ 	VSDParser.cpp \
++	VSDMetaData.cpp \
+ 	VSDShapeList.cpp \
+ 	VSDStencils.cpp \
+ 	VSDStyles.cpp \
+@@ -58,6 +59,7 @@ libvisio_ at VSD_MAJOR_VERSION@_ at VSD_MINOR_VERSION@_la_SOURCES = \
+ 	VSDPages.h \
+ 	VSDParagraphList.h \
+ 	VSDParser.h \
++	VSDMetaData.h \
+ 	VSDShapeList.h \
+ 	VSDStencils.h \
+ 	VSDStyles.h \
+diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in
+index a51ac14..0f8dd91 100644
+--- a/src/lib/Makefile.in
++++ b/src/lib/Makefile.in
+@@ -131,10 +131,10 @@ am_libvisio_ at VSD_MAJOR_VERSION@_ at VSD_MINOR_VERSION@_la_OBJECTS =  \
+ 	VSDInternalStream.lo VSDCharacterList.lo \
+ 	VSDContentCollector.lo VSDFieldList.lo VSDGeometryList.lo \
+ 	VSDOutputElementList.lo VSDPages.lo VSDParagraphList.lo \
+-	VSDParser.lo VSDShapeList.lo VSDStencils.lo VSDStyles.lo \
+-	VSDStylesCollector.lo VSDXMLHelper.lo VDXParser.lo \
+-	VSDXMLParserBase.lo VSDXMLTokenMap.lo VSDXParser.lo \
+-	VSDXTheme.lo VSDXMetaData.lo $(am__objects_1)
++	VSDParser.lo VSDMetaData.lo VSDShapeList.lo VSDStencils.lo \
++	VSDStyles.lo VSDStylesCollector.lo VSDXMLHelper.lo \
++	VDXParser.lo VSDXMLParserBase.lo VSDXMLTokenMap.lo \
++	VSDXParser.lo VSDXTheme.lo VSDXMetaData.lo $(am__objects_1)
+ libvisio_ at VSD_MAJOR_VERSION@_ at VSD_MINOR_VERSION@_la_OBJECTS = $(am_libvisio_ at VSD_MAJOR_VERSION@_ at VSD_MINOR_VERSION@_la_OBJECTS)
+ AM_V_lt = $(am__v_lt_ at AM_V@)
+ am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
+@@ -400,6 +400,7 @@ libvisio_ at VSD_MAJOR_VERSION@_ at VSD_MINOR_VERSION@_la_SOURCES = \
+ 	VSDPages.cpp \
+ 	VSDParagraphList.cpp \
+ 	VSDParser.cpp \
++	VSDMetaData.cpp \
+ 	VSDShapeList.cpp \
+ 	VSDStencils.cpp \
+ 	VSDStyles.cpp \
+@@ -419,6 +420,7 @@ libvisio_ at VSD_MAJOR_VERSION@_ at VSD_MINOR_VERSION@_la_SOURCES = \
+ 	VSDPages.h \
+ 	VSDParagraphList.h \
+ 	VSDParser.h \
++	VSDMetaData.h \
+ 	VSDShapeList.h \
+ 	VSDStencils.h \
+ 	VSDStyles.h \
+@@ -539,6 +541,7 @@ distclean-compile:
+ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/VSDFieldList.Plo at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/VSDGeometryList.Plo at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/VSDInternalStream.Plo at am__quote@
++ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/VSDMetaData.Plo at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/VSDOutputElementList.Plo at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/VSDPages.Plo at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/VSDParagraphList.Plo at am__quote@
+diff --git a/src/lib/VSDMetaData.cpp b/src/lib/VSDMetaData.cpp
+new file mode 100644
+index 0000000..209cc34
+--- /dev/null
++++ b/src/lib/VSDMetaData.cpp
+@@ -0,0 +1,180 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/*
++ * This file is part of the libvisio project.
++ *
++ * This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ */
++
++#include "VSDMetaData.h"
++#include <unicode/ucnv.h>
++
++libvisio::VSDMetaData::VSDMetaData()
++{
++}
++
++libvisio::VSDMetaData::~VSDMetaData()
++{
++}
++
++bool libvisio::VSDMetaData::parse(librevenge::RVNGInputStream *input)
++{
++  if (!input)
++    return false;
++
++  readPropertySetStream(input);
++
++  return true;
++}
++
++void libvisio::VSDMetaData::readPropertySetStream(librevenge::RVNGInputStream *input)
++{
++  // ByteOrder
++  input->seek(2, librevenge::RVNG_SEEK_CUR);
++  // Version
++  input->seek(2, librevenge::RVNG_SEEK_CUR);
++  // SystemIdentifier
++  input->seek(4, librevenge::RVNG_SEEK_CUR);
++  // CLSID
++  input->seek(16, librevenge::RVNG_SEEK_CUR);
++  // NumPropertySets
++  input->seek(4, librevenge::RVNG_SEEK_CUR);
++  // FMTID0
++  input->seek(16, librevenge::RVNG_SEEK_CUR);
++  uint32_t offset0 = readU32(input);
++  readPropertySet(input, offset0);
++}
++
++void libvisio::VSDMetaData::readPropertySet(librevenge::RVNGInputStream *input, uint32_t offset)
++{
++  input->seek(offset, librevenge::RVNG_SEEK_SET);
++
++  // Size
++  input->seek(4, librevenge::RVNG_SEEK_CUR);
++  uint32_t numProperties = readU32(input);
++  for (uint32_t i = 0; i < numProperties; ++i)
++    readPropertyIdentifierAndOffset(input);
++  for (uint32_t i = 0; i < numProperties; ++i)
++  {
++    if (i >= m_idsAndOffsets.size())
++      break;
++    readTypedPropertyValue(input, i, offset + m_idsAndOffsets[i].second);
++  }
++}
++
++#define CODEPAGE_PROPERTY_IDENTIFIER 0x00000001
++
++uint32_t libvisio::VSDMetaData::getCodePage()
++{
++  for (size_t i = 0; i < m_idsAndOffsets.size(); ++i)
++  {
++    if (m_idsAndOffsets[i].first == CODEPAGE_PROPERTY_IDENTIFIER)
++    {
++      if (i >= m_typedPropertyValues.size())
++        break;
++      return m_typedPropertyValues[i];
++    }
++  }
++
++  return 0;
++}
++
++void libvisio::VSDMetaData::readPropertyIdentifierAndOffset(librevenge::RVNGInputStream *input)
++{
++  uint32_t propertyIdentifier = readU32(input);
++  uint32_t offset = readU32(input);
++  m_idsAndOffsets.push_back(std::make_pair(propertyIdentifier, offset));
++}
++
++#define VT_I2 0x0002
++#define VT_LPSTR 0x001E
++
++#define PIDSI_TITLE 0x00000002
++
++void libvisio::VSDMetaData::readTypedPropertyValue(librevenge::RVNGInputStream *input, uint32_t index, uint32_t offset)
++{
++  input->seek(offset, librevenge::RVNG_SEEK_SET);
++  uint16_t type = readU16(input);
++  // Padding
++  input->seek(2, librevenge::RVNG_SEEK_CUR);
++
++  if (type == VT_I2)
++  {
++    uint16_t value = readU16(input);
++    m_typedPropertyValues[index] = value;
++  }
++  else if (type == VT_LPSTR)
++  {
++    librevenge::RVNGString string = readCodePageString(input);
++    if (!string.empty())
++    {
++      if (index >= m_idsAndOffsets.size())
++        return;
++
++      switch (m_idsAndOffsets[index].first)
++      {
++      case PIDSI_TITLE:
++        m_metaData.insert("dc:title", string);
++        break;
++      }
++    }
++  }
++}
++
++librevenge::RVNGString libvisio::VSDMetaData::readCodePageString(librevenge::RVNGInputStream *input)
++{
++  uint32_t size = readU32(input);
++
++  std::vector<unsigned char> characters;
++  for (uint32_t i = 0; i < size; ++i)
++    characters.push_back(readU8(input));
++
++  uint32_t codepage = getCodePage();
++  librevenge::RVNGString string;
++
++  if (codepage == 65001)
++  {
++    // http://msdn.microsoft.com/en-us/library/windows/desktop/dd374130%28v=vs.85%29.aspx
++    // says this is UTF-8.
++    for (std::vector<unsigned char>::const_iterator i = characters.begin(); i != characters.end(); ++i)
++      string.append((const char)*i);
++  }
++  else
++  {
++    UErrorCode status = U_ZERO_ERROR;
++    UConverter *conv = 0;
++
++    switch (codepage)
++    {
++    case 1252:
++      // http://msdn.microsoft.com/en-us/goglobal/bb964654
++      conv = ucnv_open("windows-1252", &status);
++      break;
++    }
++
++    if (U_SUCCESS(status) && conv)
++    {
++      const char *src = (const char *)&characters[0];
++      const char *srcLimit = (const char *)src + characters.size();
++      while (src < srcLimit)
++      {
++        UChar32 ucs4Character = ucnv_getNextUChar(conv, &src, srcLimit, &status);
++        if (U_SUCCESS(status) && U_IS_UNICODE_CHAR(ucs4Character))
++          appendUCS4(string, ucs4Character);
++      }
++    }
++
++    if (conv)
++      ucnv_close(conv);
++  }
++
++  return string;
++}
++
++const librevenge::RVNGPropertyList &libvisio::VSDMetaData::getMetaData()
++{
++  return m_metaData;
++}
++
++/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
+diff --git a/src/lib/VSDMetaData.h b/src/lib/VSDMetaData.h
+new file mode 100644
+index 0000000..c185894
+--- /dev/null
++++ b/src/lib/VSDMetaData.h
+@@ -0,0 +1,51 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/*
++ * This file is part of the libvisio project.
++ *
++ * This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
++ */
++
++#ifndef __VSDMETADATA_H__
++#define __VSDMETADATA_H__
++
++#include <vector>
++#include <utility>
++#include <map>
++#include <librevenge-stream/librevenge-stream.h>
++#include <librevenge/librevenge.h>
++#include "libvisio_utils.h"
++
++namespace libvisio
++{
++
++class VSDMetaData
++{
++public:
++  VSDMetaData();
++  ~VSDMetaData();
++  bool parse(librevenge::RVNGInputStream *input);
++  const librevenge::RVNGPropertyList &getMetaData();
++
++private:
++  VSDMetaData(const VSDMetaData &);
++  VSDMetaData &operator=(const VSDMetaData &);
++
++  void readPropertySetStream(librevenge::RVNGInputStream *input);
++  void readPropertySet(librevenge::RVNGInputStream *input, uint32_t offset);
++  void readPropertyIdentifierAndOffset(librevenge::RVNGInputStream *input);
++  void readTypedPropertyValue(librevenge::RVNGInputStream *input, uint32_t index, uint32_t offset);
++  librevenge::RVNGString readCodePageString(librevenge::RVNGInputStream *input);
++
++  uint32_t getCodePage();
++
++  std::vector< std::pair<uint32_t, uint32_t> > m_idsAndOffsets;
++  std::map<uint16_t, uint16_t> m_typedPropertyValues;
++  librevenge::RVNGPropertyList m_metaData;
++};
++
++} // namespace libvisio
++
++#endif // __VSDMETADATA_H__
++/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
+diff --git a/src/lib/VSDParser.cpp b/src/lib/VSDParser.cpp
+index 1b8133f..9d6e175 100644
+--- a/src/lib/VSDParser.cpp
++++ b/src/lib/VSDParser.cpp
+@@ -19,9 +19,10 @@
+ #include "VSDDocumentStructure.h"
+ #include "VSDContentCollector.h"
+ #include "VSDStylesCollector.h"
++#include "VSDMetaData.h"
+ 
+-libvisio::VSDParser::VSDParser(librevenge::RVNGInputStream *input, librevenge::RVNGDrawingInterface *painter)
+-  : m_input(input), m_painter(painter), m_header(), m_collector(0), m_shapeList(), m_currentLevel(0),
++libvisio::VSDParser::VSDParser(librevenge::RVNGInputStream *input, librevenge::RVNGDrawingInterface *painter, librevenge::RVNGInputStream *container)
++  : m_input(input), m_painter(painter), m_container(container), m_header(), m_collector(0), m_shapeList(), m_currentLevel(0),
+     m_stencils(), m_currentStencil(0), m_shape(), m_isStencilStarted(false), m_isInStyles(false),
+     m_currentShapeLevel(0), m_currentShapeID(MINUS_ONE), m_extractStencils(false), m_colours(),
+     m_isBackgroundPage(false), m_isShapeStarted(false), m_shadowOffsetX(0.0), m_shadowOffsetY(0.0),
+@@ -136,6 +137,9 @@ bool libvisio::VSDParser::parseMain()
+ 
+   VSDContentCollector contentCollector(m_painter, groupXFormsSequence, groupMembershipsSequence, documentPageShapeOrders, styles, m_stencils);
+   m_collector = &contentCollector;
++  if (m_container)
++    parseMetaData();
++
+   VSD_DEBUG_MSG(("VSDParser::parseMain 2nd pass\n"));
+   if (!parseDocument(&trailerStream, shift))
+     return false;
+@@ -143,6 +147,25 @@ bool libvisio::VSDParser::parseMain()
+   return true;
+ }
+ 
++bool libvisio::VSDParser::parseMetaData()
++{
++  if (!m_container)
++    return false;
++  m_container->seek(0, librevenge::RVNG_SEEK_SET);
++  if (!m_container->isStructured())
++    return false;
++  librevenge::RVNGInputStream *stream = m_container->getSubStreamByName("\x05SummaryInformation");
++  if (!stream)
++    return false;
++
++  VSDMetaData metaData;
++  metaData.parse(stream);
++  m_collector->collectMetaData(metaData.getMetaData());
++
++  delete stream;
++  return true;
++}
++
+ bool libvisio::VSDParser::parseDocument(librevenge::RVNGInputStream *input, unsigned shift)
+ {
+   try
+diff --git a/src/lib/VSDParser.h b/src/lib/VSDParser.h
+index aabb0db..b2bba54 100644
+--- a/src/lib/VSDParser.h
++++ b/src/lib/VSDParser.h
+@@ -45,7 +45,7 @@ struct Pointer
+ class VSDParser
+ {
+ public:
+-  explicit VSDParser(librevenge::RVNGInputStream *input, librevenge::RVNGDrawingInterface *painter);
++  explicit VSDParser(librevenge::RVNGInputStream *input, librevenge::RVNGDrawingInterface *painter, librevenge::RVNGInputStream *container = 0);
+   virtual ~VSDParser();
+   bool parseMain();
+   bool extractStencils();
+@@ -113,6 +113,8 @@ protected:
+   // parser of one pass
+   bool parseDocument(librevenge::RVNGInputStream *input, unsigned shift);
+ 
++  bool parseMetaData();
++
+   // Stream handlers
+   void handleStreams(librevenge::RVNGInputStream *input, unsigned ptrType, unsigned shift, unsigned level);
+   void handleStream(const Pointer &ptr, unsigned idx, unsigned level);
+@@ -133,6 +135,7 @@ protected:
+ 
+   librevenge::RVNGInputStream *m_input;
+   librevenge::RVNGDrawingInterface *m_painter;
++  librevenge::RVNGInputStream *m_container;
+   ChunkHeader m_header;
+   VSDCollector *m_collector;
+   VSDShapeList m_shapeList;
+diff --git a/src/lib/VisioDocument.cpp b/src/lib/VisioDocument.cpp
+index be14b68..f834478 100644
+--- a/src/lib/VisioDocument.cpp
++++ b/src/lib/VisioDocument.cpp
+@@ -158,7 +158,7 @@ static bool parseBinaryVisioDocument(librevenge::RVNGInputStream *input, libreve
+       parser = new libvisio::VSD6Parser(docStream, painter);
+       break;
+     case 11:
+-      parser = new libvisio::VSDParser(docStream, painter);
++      parser = new libvisio::VSDParser(docStream, painter, input);
+       break;
+     default:
+       break;
+commit 2e467f4e487bd8fd8440057e1d79f89b2a966419
+Author: Miklos Vajna <vmiklos at collabora.co.uk>
+Date:   Tue Dec 2 17:02:14 2014 +0100
+
+    fdo#86664 VSD: import Creation/ModifiedTime
+
+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 9d6e175..3af5bd0 100644
+--- a/src/lib/VSDParser.cpp
++++ b/src/lib/VSDParser.cpp
+@@ -160,6 +160,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;
+commit 89ccb97fedc69e4508581ddcd93c9ea6740855c1
+Author: Miklos Vajna <vmiklos at collabora.co.uk>
+Date:   Tue Dec 2 18:50:16 2014 +0100
+
+    error C3861: ´localtime´: identifier not found
+    
+    Change-Id: Ic0ccfc0b6cdd030772d09e7d235c63d440ba2f1b
+
+diff --git a/src/lib/VSDMetaData.cpp b/src/lib/VSDMetaData.cpp
+index 3fd5bf9..61f01a9 100644
+--- a/src/lib/VSDMetaData.cpp
++++ b/src/lib/VSDMetaData.cpp
+@@ -10,6 +10,7 @@
+ #include "VSDMetaData.h"
+ #include <cmath>
+ #include <unicode/ucnv.h>
++#include <ctime>
+ 
+ libvisio::VSDMetaData::VSDMetaData()
+ {


More information about the Libreoffice-commits mailing list