Coverage Report

Created: 2026-07-20 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libvisio/src/lib/VSDXMetaData.cpp
Line
Count
Source
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
18
libvisio::VSDXMetaData::VSDXMetaData()
19
1.22k
  : m_metaData()
20
1.22k
{
21
1.22k
}
22
23
libvisio::VSDXMetaData::~VSDXMetaData()
24
1.22k
{
25
1.22k
}
26
27
librevenge::RVNGString libvisio::VSDXMetaData::readString(xmlTextReaderPtr reader, int stringTokenId)
28
5.21k
{
29
5.21k
  int ret = 1;
30
5.21k
  int tokenId = XML_TOKEN_INVALID;
31
5.21k
  int tokenType = -1;
32
5.21k
  librevenge::RVNGString string;
33
5.21k
  do
34
9.50k
  {
35
9.50k
    ret = xmlTextReaderRead(reader);
36
9.50k
    tokenId = getElementToken(reader);
37
9.50k
    tokenType = xmlTextReaderNodeType(reader);
38
9.50k
    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT)
39
2.98k
      string.append((const char *)xmlTextReaderConstValue(reader));
40
9.50k
  }
41
9.50k
  while ((stringTokenId != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
42
5.21k
  return string;
43
5.21k
}
44
45
void libvisio::VSDXMetaData::readCoreProperties(xmlTextReaderPtr reader)
46
1.02k
{
47
1.02k
  int ret = 1;
48
1.02k
  int tokenId = XML_TOKEN_INVALID;
49
1.02k
  int tokenType = -1;
50
1.02k
  do
51
37.9k
  {
52
37.9k
    ret = xmlTextReaderRead(reader);
53
37.9k
    tokenId = getElementToken(reader);
54
37.9k
    if (XML_TOKEN_INVALID == tokenId)
55
31.9k
    {
56
31.9k
      VSD_DEBUG_MSG(("VSDXMetaData::readCoreProperties: unknown token %s\n", xmlTextReaderConstName(reader)));
57
31.9k
    }
58
37.9k
    tokenType = xmlTextReaderNodeType(reader);
59
60
37.9k
    if (tokenType != XML_READER_TYPE_ELEMENT)
61
20.2k
      continue;
62
63
17.7k
    switch (tokenId)
64
17.7k
    {
65
468
    case XML_DC_TITLE:
66
468
      m_metaData.insert("dc:title", readString(reader, XML_DC_TITLE));
67
468
      break;
68
453
    case XML_DC_SUBJECT:
69
453
      m_metaData.insert("dc:subject", readString(reader, XML_DC_SUBJECT));
70
453
      break;
71
443
    case XML_DC_CREATOR:
72
443
      m_metaData.insert("meta:initial-creator", readString(reader, XML_DC_CREATOR));
73
443
      break;
74
385
    case XML_DCTERMS_CREATED:
75
385
      m_metaData.insert("meta:creation-date", readString(reader, XML_DCTERMS_CREATED));
76
385
      break;
77
383
    case XML_DCTERMS_MODIFIED:
78
383
      m_metaData.insert("dc:date", readString(reader, XML_DCTERMS_MODIFIED));
79
383
      break;
80
435
    case XML_CP_KEYWORDS:
81
435
      m_metaData.insert("meta:keyword", readString(reader, XML_CP_KEYWORDS));
82
435
      break;
83
445
    case XML_DC_DESCRIPTION:
84
445
      m_metaData.insert("dc:description", readString(reader, XML_DC_DESCRIPTION));
85
445
      break;
86
445
    case XML_CP_LASTMODIFIEDBY:
87
445
      m_metaData.insert("dc:creator", readString(reader, XML_CP_LASTMODIFIEDBY));
88
445
      break;
89
384
    case XML_DC_LANGUAGE:
90
384
      m_metaData.insert("dc:language", readString(reader, XML_DC_LANGUAGE));
91
384
      break;
92
383
    case XML_CP_CATEGORY:
93
383
      m_metaData.insert("librevenge:category", readString(reader, XML_CP_CATEGORY));
94
383
      break;
95
449
    case XML_COMPANY:
96
449
      m_metaData.insert("librevenge:company", readString(reader, XML_COMPANY));
97
449
      break;
98
545
    case XML_TEMPLATE:
99
545
    {
100
545
      librevenge::RVNGString templateHrefRVNG = readString(reader, XML_TEMPLATE);
101
545
      std::string templateHref(templateHrefRVNG.cstr());
102
545
      size_t found = templateHref.find_last_of("/\\");
103
545
      if (found != std::string::npos)
104
180
        templateHrefRVNG = librevenge::RVNGString(templateHref.substr(found+1).c_str());
105
545
      m_metaData.insert("librevenge:template", templateHrefRVNG);
106
545
      break;
107
0
    }
108
12.5k
    default:
109
12.5k
      break;
110
17.7k
    }
111
17.7k
  }
112
37.9k
  while (((XML_CP_COREPROPERTIES != tokenId && XML_PROPERTIES != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType)
113
37.1k
         && 1 == ret);
114
1.02k
}
115
116
bool libvisio::VSDXMetaData::parse(librevenge::RVNGInputStream *input)
117
1.24k
{
118
1.24k
  if (!input)
119
0
    return false;
120
121
1.24k
  XMLErrorWatcher watcher;
122
123
1.24k
  auto reader = xmlReaderForStream(input, &watcher, false);
124
1.24k
  if (!reader)
125
0
    return false;
126
127
1.24k
  try
128
1.24k
  {
129
1.24k
    int ret = xmlTextReaderRead(reader.get());
130
3.57k
    while (1 == ret && !watcher.isError())
131
2.33k
    {
132
2.33k
      int tokenId = getElementToken(reader.get());
133
2.33k
      switch (tokenId)
134
2.33k
      {
135
492
      case XML_CP_COREPROPERTIES:
136
1.02k
      case XML_PROPERTIES:
137
1.02k
        readCoreProperties(reader.get());
138
1.02k
        break;
139
1.30k
      default:
140
1.30k
        break;
141
142
2.33k
      }
143
2.33k
      ret = xmlTextReaderRead(reader.get());
144
2.33k
    }
145
1.24k
  }
146
1.24k
  catch (...)
147
1.24k
  {
148
0
    return false;
149
0
  }
150
151
1.24k
  return !watcher.isError();
152
1.24k
}
153
154
int libvisio::VSDXMetaData::getElementToken(xmlTextReaderPtr reader)
155
49.8k
{
156
49.8k
  return VSDXMLTokenMap::getTokenId(xmlTextReaderConstName(reader));
157
49.8k
}
158
159
const librevenge::RVNGPropertyList &libvisio::VSDXMetaData::getMetaData()
160
1.22k
{
161
1.22k
  return m_metaData;
162
1.22k
}
163
164
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */