1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3  * This file is part of the libvisio project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #include "VSDXMetaData.h"
11 
12 #include "VSDXMLTokenMap.h"
13 #include "libvisio_utils.h"
14 #include "libvisio_xml.h"
15 #include <memory>
16 #include <string>
17 
VSDXMetaData()18 libvisio::VSDXMetaData::VSDXMetaData()
19   : m_metaData()
20 {
21 }
22 
~VSDXMetaData()23 libvisio::VSDXMetaData::~VSDXMetaData()
24 {
25 }
26 
readString(xmlTextReaderPtr reader,int stringTokenId)27 librevenge::RVNGString libvisio::VSDXMetaData::readString(xmlTextReaderPtr reader, int stringTokenId)
28 {
29   int ret = 1;
30   int tokenId = XML_TOKEN_INVALID;
31   int tokenType = -1;
32   librevenge::RVNGString string;
33   do
34   {
35     ret = xmlTextReaderRead(reader);
36     tokenId = getElementToken(reader);
37     tokenType = xmlTextReaderNodeType(reader);
38     if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT)
39       string.append((const char *)xmlTextReaderConstValue(reader));
40   }
41   while ((stringTokenId != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
42   return string;
43 }
44 
readCoreProperties(xmlTextReaderPtr reader)45 void libvisio::VSDXMetaData::readCoreProperties(xmlTextReaderPtr reader)
46 {
47   int ret = 1;
48   int tokenId = XML_TOKEN_INVALID;
49   int tokenType = -1;
50   do
51   {
52     ret = xmlTextReaderRead(reader);
53     tokenId = getElementToken(reader);
54     if (XML_TOKEN_INVALID == tokenId)
55     {
56       VSD_DEBUG_MSG(("VSDXMetaData::readCoreProperties: unknown token %s\n", xmlTextReaderConstName(reader)));
57     }
58     tokenType = xmlTextReaderNodeType(reader);
59 
60     if (tokenType != XML_READER_TYPE_ELEMENT)
61       continue;
62 
63     switch (tokenId)
64     {
65     case XML_DC_TITLE:
66       m_metaData.insert("dc:title", readString(reader, XML_DC_TITLE));
67       break;
68     case XML_DC_SUBJECT:
69       m_metaData.insert("dc:subject", readString(reader, XML_DC_SUBJECT));
70       break;
71     case XML_DC_CREATOR:
72       m_metaData.insert("meta:initial-creator", readString(reader, XML_DC_CREATOR));
73       break;
74     case XML_DCTERMS_CREATED:
75       m_metaData.insert("meta:creation-date", readString(reader, XML_DCTERMS_CREATED));
76       break;
77     case XML_DCTERMS_MODIFIED:
78       m_metaData.insert("dc:date", readString(reader, XML_DCTERMS_MODIFIED));
79       break;
80     case XML_CP_KEYWORDS:
81       m_metaData.insert("meta:keyword", readString(reader, XML_CP_KEYWORDS));
82       break;
83     case XML_DC_DESCRIPTION:
84       m_metaData.insert("dc:description", readString(reader, XML_DC_DESCRIPTION));
85       break;
86     case XML_CP_LASTMODIFIEDBY:
87       m_metaData.insert("dc:creator", readString(reader, XML_CP_LASTMODIFIEDBY));
88       break;
89     case XML_DC_LANGUAGE:
90       m_metaData.insert("dc:language", readString(reader, XML_DC_LANGUAGE));
91       break;
92     case XML_CP_CATEGORY:
93       m_metaData.insert("librevenge:category", readString(reader, XML_CP_CATEGORY));
94       break;
95     case XML_COMPANY:
96       m_metaData.insert("librevenge:company", readString(reader, XML_COMPANY));
97       break;
98     case XML_TEMPLATE:
99     {
100       librevenge::RVNGString templateHrefRVNG = readString(reader, XML_TEMPLATE);
101       std::string templateHref(templateHrefRVNG.cstr());
102       size_t found = templateHref.find_last_of("/\\");
103       if (found != std::string::npos)
104         templateHrefRVNG = librevenge::RVNGString(templateHref.substr(found+1).c_str());
105       m_metaData.insert("librevenge:template", templateHrefRVNG);
106       break;
107     }
108     default:
109       break;
110     }
111   }
112   while (((XML_CP_COREPROPERTIES != tokenId && XML_PROPERTIES != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType)
113          && 1 == ret);
114 }
115 
parse(librevenge::RVNGInputStream * input)116 bool libvisio::VSDXMetaData::parse(librevenge::RVNGInputStream *input)
117 {
118   if (!input)
119     return false;
120 
121   XMLErrorWatcher watcher;
122 
123   auto reader = xmlReaderForStream(input, &watcher, false);
124   if (!reader)
125     return false;
126 
127   try
128   {
129     int ret = xmlTextReaderRead(reader.get());
130     while (1 == ret && !watcher.isError())
131     {
132       int tokenId = getElementToken(reader.get());
133       switch (tokenId)
134       {
135       case XML_CP_COREPROPERTIES:
136       case XML_PROPERTIES:
137         readCoreProperties(reader.get());
138         break;
139       default:
140         break;
141 
142       }
143       ret = xmlTextReaderRead(reader.get());
144     }
145   }
146   catch (...)
147   {
148     return false;
149   }
150 
151   return !watcher.isError();
152 }
153 
getElementToken(xmlTextReaderPtr reader)154 int libvisio::VSDXMetaData::getElementToken(xmlTextReaderPtr reader)
155 {
156   return VSDXMLTokenMap::getTokenId(xmlTextReaderConstName(reader));
157 }
158 
getMetaData()159 const librevenge::RVNGPropertyList &libvisio::VSDXMetaData::getMetaData()
160 {
161   return m_metaData;
162 }
163 
164 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */
165