summaryrefslogtreecommitdiff
path: root/src/lib/libvisio_xml.cpp
blob: 9941ee9c28ea5c179fc16e4f6704ffc5231c94e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/* -*- 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 "libvisio_xml.h"

#include <boost/lexical_cast.hpp>

#include "VSDTypes.h"
#include "libvisio_utils.h"

namespace libvisio
{

namespace
{

extern "C"
{

  static int vsdxInputCloseFunc(void *)
  {
    return 0;
  }

  static int vsdxInputReadFunc(void *context, char *buffer, int len)
  {
    librevenge::RVNGInputStream *input = (librevenge::RVNGInputStream *)context;

    if ((!input) || (!buffer) || (len < 0))
      return -1;

    if (input->isEnd())
      return 0;

    unsigned long tmpNumBytesRead = 0;
    const unsigned char *tmpBuffer = input->read(len, tmpNumBytesRead);

    if (tmpBuffer && tmpNumBytesRead)
      memcpy(buffer, tmpBuffer, tmpNumBytesRead);
    return tmpNumBytesRead;
  }

#ifdef DEBUG
  static void vsdxReaderErrorFunc(void *arg, const char *message, xmlParserSeverities severity, xmlTextReaderLocatorPtr)
#else
  static void vsdxReaderErrorFunc(void *arg, const char *, xmlParserSeverities severity, xmlTextReaderLocatorPtr)
#endif
  {
    XMLErrorWatcher *const watcher = reinterpret_cast<XMLErrorWatcher *>(arg);
    switch (severity)
    {
    case XML_PARSER_SEVERITY_VALIDITY_WARNING:
      VSD_DEBUG_MSG(("Found xml parser severity validity warning %s\n", message));
      break;
    case XML_PARSER_SEVERITY_VALIDITY_ERROR:
      VSD_DEBUG_MSG(("Found xml parser severity validity error %s\n", message));
      break;
    case XML_PARSER_SEVERITY_WARNING:
      VSD_DEBUG_MSG(("Found xml parser severity warning %s\n", message));
      break;
    case XML_PARSER_SEVERITY_ERROR:
      VSD_DEBUG_MSG(("Found xml parser severity error %s\n", message));
      if (watcher)
        watcher->setError();
      break;
    default:
      break;
    }
  }

} // extern "C"

} // anonymous namespace

XMLErrorWatcher::XMLErrorWatcher()
  : m_error(false)
{
}

bool XMLErrorWatcher::isError() const
{
  return m_error;
}

void XMLErrorWatcher::setError()
{
  m_error = true;
}

xmlTextReaderPtr xmlReaderForStream(librevenge::RVNGInputStream *input, const char *URL, const char *encoding, int options, XMLErrorWatcher *const watcher)
{
  xmlTextReaderPtr reader = xmlReaderForIO(vsdxInputReadFunc, vsdxInputCloseFunc, (void *)input, URL, encoding, options);
  xmlTextReaderSetErrorHandler(reader, vsdxReaderErrorFunc, watcher);
  return reader;
}

Colour xmlStringToColour(const xmlChar *s)
{
  if (xmlStrEqual(s, BAD_CAST("Themed")))
    return Colour();
  std::string str((const char *)s);
  if (str[0] == '#')
  {
    if (str.length() != 7)
    {
      VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
      throw XmlParserException();
    }
    else
      str.erase(str.begin());
  }
  else
  {
    if (str.length() != 6)
    {
      VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
      throw XmlParserException();
    }
  }

  std::istringstream istr(str);
  unsigned val = 0;
  istr >> std::hex >> val;

  return Colour((val & 0xff0000) >> 16, (val & 0xff00) >> 8, val & 0xff, 0);
}

Colour xmlStringToColour(const boost::shared_ptr<xmlChar> &s)
{
  return xmlStringToColour(s.get());
}

long xmlStringToLong(const xmlChar *s)
{
  using boost::lexical_cast;
  using boost::bad_lexical_cast;
  if (xmlStrEqual(s, BAD_CAST("Themed")))
    return 0;

  try
  {
    return boost::lexical_cast<long, const char *>((const char *)s);
  }
  catch (const boost::bad_lexical_cast &)
  {
    VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
    throw XmlParserException();
  }
  return 0;
}

long xmlStringToLong(const boost::shared_ptr<xmlChar> &s)
{
  return xmlStringToLong(s.get());
}

double xmlStringToDouble(const xmlChar *s) try
{
  if (xmlStrEqual(s, BAD_CAST("Themed")))
    return 0.0;

  return boost::lexical_cast<double, const char *>((const char *)s);
}
catch (const boost::bad_lexical_cast &)
{
  VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
  throw XmlParserException();
}

double xmlStringToDouble(const boost::shared_ptr<xmlChar> &s)
{
  return xmlStringToDouble(s.get());
}

bool xmlStringToBool(const xmlChar *s)
{
  if (xmlStrEqual(s, BAD_CAST("Themed")))
    return 0;

  bool value = false;
  if (xmlStrEqual(s, BAD_CAST("true")) || xmlStrEqual(s, BAD_CAST("1")))
    value = true;
  else if (xmlStrEqual(s, BAD_CAST("false")) || xmlStrEqual(s, BAD_CAST("0")))
    value = false;
  else
  {
    VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
    throw XmlParserException();
  }
  return value;

}

bool xmlStringToBool(const boost::shared_ptr<xmlChar> &s)
{
  return xmlStringToBool(s.get());
}

} // namespace libvisio

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */