1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6  */
7 
8 #include "orcus/types.hpp"
9 #include "orcus/global.hpp"
10 #include "orcus/xml_namespace.hpp"
11 
12 #include <limits>
13 #include <sstream>
14 #include <mdds/sorted_string_map.hpp>
15 
16 namespace orcus {
17 
18 const xmlns_id_t XMLNS_UNKNOWN_ID = nullptr;
19 const xml_token_t XML_UNKNOWN_TOKEN = 0;
20 
operator ()(const xml_token_pair_t & v) const21 size_t xml_token_pair_hash::operator()(const xml_token_pair_t& v) const
22 {
23     return std::hash<const char*>()(v.first) ^ std::hash<size_t>()(v.second);
24 }
25 
26 const size_t index_not_found = std::numeric_limits<size_t>::max();
27 
xml_name_t()28 xml_name_t::xml_name_t() : ns(XMLNS_UNKNOWN_ID), name() {}
xml_name_t(xmlns_id_t _ns,const pstring & _name)29 xml_name_t::xml_name_t(xmlns_id_t _ns, const pstring& _name) : ns(_ns), name(_name) {}
xml_name_t(const xml_name_t & r)30 xml_name_t::xml_name_t(const xml_name_t& r) : ns(r.ns), name(r.name) {}
31 
operator =(const xml_name_t & other)32 xml_name_t& xml_name_t::operator= (const xml_name_t& other)
33 {
34     ns = other.ns;
35     name = other.name;
36     return *this;
37 }
38 
operator ==(const xml_name_t & other) const39 bool xml_name_t::operator== (const xml_name_t& other) const
40 {
41     return ns == other.ns && name == other.name;
42 }
43 
operator !=(const xml_name_t & other) const44 bool xml_name_t::operator!= (const xml_name_t& other) const
45 {
46     return !operator==(other);
47 }
48 
to_string(const xmlns_context & cxt,to_string_type type) const49 std::string xml_name_t::to_string(const xmlns_context& cxt, to_string_type type) const
50 {
51     std::ostringstream os;
52 
53     if (ns)
54     {
55         pstring ns_str;
56         switch (type)
57         {
58             case use_alias:
59                 ns_str = cxt.get_alias(ns);
60                 break;
61             case use_short_name:
62                 ns_str = cxt.get_short_name(ns);
63                 break;
64 
65         }
66         if (!ns_str.empty())
67             os << ns_str << ':';
68     }
69     os << name;
70 
71     return os.str();
72 }
73 
to_string(const xmlns_repository & repo) const74 std::string xml_name_t::to_string(const xmlns_repository& repo) const
75 {
76     std::ostringstream os;
77 
78     if (ns)
79     {
80         pstring ns_str = repo.get_short_name(ns);
81         if (!ns_str.empty())
82             os << ns_str << ':';
83     }
84     os << name;
85 
86     return os.str();
87 }
88 
xml_token_attr_t()89 xml_token_attr_t::xml_token_attr_t() :
90     ns(XMLNS_UNKNOWN_ID), name(XML_UNKNOWN_TOKEN), transient(false) {}
91 
xml_token_attr_t(xmlns_id_t _ns,xml_token_t _name,const pstring & _value,bool _transient)92 xml_token_attr_t::xml_token_attr_t(
93     xmlns_id_t _ns, xml_token_t _name, const pstring& _value, bool _transient) :
94     ns(_ns), name(_name), value(_value), transient(_transient) {}
95 
xml_token_attr_t(xmlns_id_t _ns,xml_token_t _name,const pstring & _raw_name,const pstring & _value,bool _transient)96 xml_token_attr_t::xml_token_attr_t(
97     xmlns_id_t _ns, xml_token_t _name, const pstring& _raw_name, const pstring& _value, bool _transient) :
98     ns(_ns), name(_name), raw_name(_raw_name), value(_value), transient(_transient) {}
99 
xml_token_element_t()100 xml_token_element_t::xml_token_element_t() : ns(nullptr), name(XML_UNKNOWN_TOKEN) {}
101 
xml_token_element_t(xmlns_id_t _ns,xml_token_t _name,const pstring & _raw_name,std::vector<xml_token_attr_t> && _attrs)102 xml_token_element_t::xml_token_element_t(
103     xmlns_id_t _ns, xml_token_t _name, const pstring& _raw_name, std::vector<xml_token_attr_t>&& _attrs)  :
104     ns(_ns), name(_name), raw_name(_raw_name), attrs(std::move(_attrs)) {}
105 
xml_token_element_t(const xml_token_element_t & other)106 xml_token_element_t::xml_token_element_t(const xml_token_element_t& other) :
107     ns(other.ns), name(other.name), raw_name(other.raw_name), attrs(other.attrs) {}
108 
xml_token_element_t(xml_token_element_t && other)109 xml_token_element_t::xml_token_element_t(xml_token_element_t&& other) :
110     ns(other.ns), name(other.name), raw_name(other.raw_name), attrs(std::move(other.attrs)) {}
111 
xml_declaration_t()112 xml_declaration_t::xml_declaration_t() :
113     version_major(1),
114     version_minor(0),
115     encoding(character_set_t::unspecified),
116     standalone(false) {}
117 
xml_declaration_t(uint8_t _version_major,uint8_t _version_minor,character_set_t _encoding,bool _standalone)118 xml_declaration_t::xml_declaration_t(uint8_t _version_major, uint8_t _version_minor, character_set_t _encoding, bool _standalone) :
119     version_major(_version_major), version_minor(_version_minor), encoding(_encoding), standalone(_standalone) {}
120 
xml_declaration_t(const xml_declaration_t & other)121 xml_declaration_t::xml_declaration_t(const xml_declaration_t& other) :
122     version_major(other.version_major),
123     version_minor(other.version_minor),
124     encoding(other.encoding),
125     standalone(other.standalone) {}
126 
~xml_declaration_t()127 xml_declaration_t::~xml_declaration_t() {}
128 
operator =(const xml_declaration_t & other)129 xml_declaration_t& xml_declaration_t::operator= (const xml_declaration_t& other)
130 {
131     version_major = other.version_major;
132     version_minor = other.version_minor;
133     encoding = other.encoding;
134     standalone = other.standalone;
135     return *this;
136 }
137 
operator ==(const xml_declaration_t & other) const138 bool xml_declaration_t::operator== (const xml_declaration_t& other) const
139 {
140     return version_major == other.version_major && version_minor == other.version_minor &&
141         encoding == other.encoding && standalone == other.standalone;
142 }
143 
operator !=(const xml_declaration_t & other) const144 bool xml_declaration_t::operator!= (const xml_declaration_t& other) const
145 {
146     return !operator== (other);
147 }
148 
length_t()149 length_t::length_t() : unit(length_unit_t::unknown), value(0.0) {}
150 
to_string() const151 std::string length_t::to_string() const
152 {
153     std::ostringstream os;
154     os << value;
155 
156     switch (unit)
157     {
158         case length_unit_t::centimeter:
159             os << " cm";
160         break;
161         case length_unit_t::inch:
162             os << " in";
163         break;
164         case length_unit_t::point:
165             os << " pt";
166         break;
167         case length_unit_t::twip:
168             os << " twip";
169         break;
170         case length_unit_t::unknown:
171         default:
172             ;
173     }
174 
175     return os.str();
176 }
177 
date_time_t()178 date_time_t::date_time_t() :
179     year(0), month(0), day(0), hour(0), minute(0), second(0.0) {}
180 
date_time_t(int _year,int _month,int _day)181 date_time_t::date_time_t(int _year, int _month, int _day) :
182     year(_year), month(_month), day(_day), hour(0), minute(0), second(0.0) {}
183 
date_time_t(int _year,int _month,int _day,int _hour,int _minute,double _second)184 date_time_t::date_time_t(int _year, int _month, int _day, int _hour, int _minute, double _second) :
185     year(_year), month(_month), day(_day), hour(_hour), minute(_minute), second(_second) {}
186 
date_time_t(const date_time_t & other)187 date_time_t::date_time_t(const date_time_t& other) :
188     year(other.year),
189     month(other.month),
190     day(other.day),
191     hour(other.hour),
192     minute(other.minute),
193     second(other.second) {}
194 
~date_time_t()195 date_time_t::~date_time_t() {}
196 
operator =(date_time_t other)197 date_time_t& date_time_t::operator= (date_time_t other)
198 {
199     swap(other);
200     return *this;
201 }
202 
swap(date_time_t & other)203 void date_time_t::swap(date_time_t& other)
204 {
205     std::swap(year, other.year);
206     std::swap(month, other.month);
207     std::swap(day, other.day);
208     std::swap(hour, other.hour);
209     std::swap(minute, other.minute);
210     std::swap(second, other.second);
211 }
212 
operator ==(const date_time_t & other) const213 bool date_time_t::operator== (const date_time_t& other) const
214 {
215     return year == other.year && month == other.month && day == other.day &&
216         hour == other.hour && minute == other.minute && second == other.second;
217 }
218 
operator !=(const date_time_t & other) const219 bool date_time_t::operator!= (const date_time_t& other) const
220 {
221     return !operator== (other);
222 }
223 
to_string() const224 std::string date_time_t::to_string() const
225 {
226     std::ostringstream os;
227     os << year << "-" << month << "-" << day << "T" << hour << ":" << minute << ":" << second;
228     return os.str();
229 }
230 
231 namespace {
232 
233 namespace dump_format {
234 
235 typedef mdds::sorted_string_map<dump_format_t> map_type;
236 
237 // Keys must be sorted.
238 const std::vector<map_type::entry> entries =
239 {
240     { ORCUS_ASCII("check"), dump_format_t::check },
241     { ORCUS_ASCII("csv"),   dump_format_t::csv   },
242     { ORCUS_ASCII("flat"),  dump_format_t::flat  },
243     { ORCUS_ASCII("html"),  dump_format_t::html  },
244     { ORCUS_ASCII("json"),  dump_format_t::json  },
245     { ORCUS_ASCII("none"),  dump_format_t::none  },
246     { ORCUS_ASCII("xml"),   dump_format_t::xml   },
247 };
248 
get()249 const map_type& get()
250 {
251     static map_type mt(entries.data(), entries.size(), dump_format_t::unknown);
252     return mt;
253 }
254 
255 } // namespace dump_format
256 
257 } // anonymous namespace
258 
to_dump_format_enum(const char * p,size_t n)259 dump_format_t to_dump_format_enum(const char* p, size_t n)
260 {
261     return dump_format::get().find(p, n);
262 }
263 
get_dump_format_entries()264 std::vector<std::pair<pstring, dump_format_t>> get_dump_format_entries()
265 {
266     std::vector<std::pair<pstring, dump_format_t>> ret;
267     for (const auto& e : dump_format::entries)
268         ret.emplace_back(pstring(e.key, e.keylen), e.value);
269 
270     return ret;
271 }
272 
operator <<(std::ostream & os,const date_time_t & v)273 std::ostream& operator<< (std::ostream& os, const date_time_t& v)
274 {
275     os << v.to_string();
276     return os;
277 }
278 
operator <<(std::ostream & os,format_t v)279 std::ostream& operator<< (std::ostream& os, format_t v)
280 {
281     static const char* values[] = {
282         "unknown",
283         "ods",
284         "xlsx",
285         "gnumeric",
286         "xls-xml",
287         "csv"
288     };
289 
290     size_t vi = static_cast<std::underlying_type_t<format_t>>(v);
291     size_t n = ORCUS_N_ELEMENTS(values);
292 
293     if (vi >= n)
294         os << "???";
295     else
296         os << values[vi];
297 
298     return os;
299 }
300 
301 }
302 
303 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
304