Current Version: 1.0.10
Project Name: csspp
unicode_range.cpp
Go to the documentation of this file.
1 // CSS Preprocessor
2 // Copyright (C) 2015-2016 Made to Order Software Corp.
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 
18 #include "csspp/unicode_range.h"
19 
20 #include "csspp/exceptions.h"
21 
22 #include <iomanip>
23 #include <iostream>
24 #include <sstream>
25 
26 namespace csspp
27 {
28 
29 namespace
30 {
31 
33 {
34  return range & 0xFFFFFFFFLL;
35 }
36 
37 wide_char_t constexpr range_to_end(range_value_t const range)
38 {
39  return (range >> 32) & 0xFFFFFFFFLL;
40 }
41 
43 {
44  return (static_cast<range_value_t>(end) << 32) | static_cast<range_value_t>(start);
45 }
46 
47 void verify_range(range_value_t const range)
48 {
49  // verify maximum
50  wide_char_t const start(range_to_start(range));
51  if(start >= 0x110000)
52  {
53  std::stringstream ss;
54  ss << "the start parameter is limited to a maximum of 0x10FFFF, it is 0x" << std::hex << start << " now.";
55  throw csspp_exception_overflow(ss.str());
56  }
57 
58  // verify minimum
59  wide_char_t const end(range_to_end(range));
60  if(end >= 0x200000) // special end to support all possible masks
61  {
62  std::stringstream ss;
63  ss << "the end parameter is limited to a maximum of 0x1FFFFF, it is 0x" << std::hex << end << " now.";
64  throw csspp_exception_overflow(ss.str());
65  }
66 
67  // must always be properly ordered
68  if(start > end)
69  {
70  std::stringstream ss;
71  ss << "the start parameter (" << std::hex << start << ") cannot be larged than the end parameter (" << end << ") in a unicode range.";
72  throw csspp_exception_overflow(ss.str());
73  }
74 }
75 
76 } // no name namespace
77 
79  : f_range(range)
80 {
82 }
83 
85  : f_range(start_end_to_range(start, end))
86 {
88 }
89 
91 {
92  verify_range(range);
93  f_range = range;
94 }
95 
97 {
98  range_value_t const range(start_end_to_range(start, end));
99  verify_range(range);
100  f_range = range;
101 }
102 
104 {
105  return f_range;
106 }
107 
109 {
110  return range_to_start(f_range);
111 }
112 
114 {
115  return range_to_end(f_range);
116 }
117 
118 std::string unicode_range_t::to_string() const
119 {
122 
123  // a special case for the 6 x '?' mask
124  if(start == 0 && end >= 0x10FFFF)
125  {
126  return "??????";
127  }
128 
129  std::stringstream ss;
130  ss << std::hex << start;
131 
132  // if start and end are equal
133  if(start == end)
134  {
135  // if equal, we return that one number
136  return ss.str();
137  }
138 
139  // check whether we can use the question mark trick
140  {
141  std::stringstream filled;
142  filled << std::hex << std::setw(6) << std::setfill('0') << start;
143  std::string const start_str(filled.str());
144  filled.str("");
145  filled << std::setw(6) << end;
146  std::string const end_str(filled.str());
147  if(start_str.length() != 6 || end_str.length() != 6)
148  {
149  throw csspp_exception_logic("unexpected string length"); // LCOV_EXCL_LINE
150  }
151  size_t p(6);
152  for(; p > 0; --p)
153  {
154  if(start_str[p - 1] != '0' || end_str[p - 1] != 'f')
155  {
156  break;
157  }
158  }
159  std::string result(start_str.substr(0, p));
160  if(result == end_str.substr(0, p))
161  {
162  // we can use a plain ??? mask
163  result += std::string("??????", 6 - p);
164  // remove leading zeroes
165  while(result.front() == '0')
166  {
167  result.erase(result.begin());
168  }
169  return result;
170  }
171  }
172 
173  // no question mark, just append the end
174  ss << "-" << end;
175 
176  return ss.str();
177 }
178 
179 } // namespace csspp
180 
181 // Local Variables:
182 // mode: cpp
183 // indent-tabs-mode: nil
184 // c-basic-offset: 4
185 // tab-width: 4
186 // End:
187 
188 // vim: ts=4 sw=4 et
void set_range(range_value_t range)
int32_t wide_char_t
Definition: csspp.h:49
wide_char_t get_end() const
range_value_t get_range() const
std::string to_string() const
void verify_range(range_value_t const range)
wide_char_t get_start() const
wide_char_t constexpr range_to_end(range_value_t const range)
wide_char_t constexpr range_to_start(range_value_t const range)
unicode_range_t(range_value_t value=0)
uint64_t range_value_t
Definition: unicode_range.h:25
range_value_t constexpr start_end_to_range(wide_char_t start, wide_char_t end)
range_value_t f_range
Definition: unicode_range.h:43

Documentation of CSS Preprocessor.

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.