1// sass.hpp must go before all system headers to get the
2// __EXTENSIONS__ fix on Solaris.
3#include "sass.hpp"
4
5#include <string>
6#include <vector>
7#include <cstdlib>
8#include <cmath>
9
10#include "utf8.h"
11
12namespace Sass {
13 namespace UTF_8 {
14
15 // naming conventions:
16 // offset: raw byte offset (0 based)
17 // position: code point offset (0 based)
18 // index: code point offset (1 based or negative)
19
20 // function that will count the number of code points (utf-8 characters) from the given beginning to the given end
21 size_t code_point_count(const sass::string& str, size_t start, size_t end) {
22 return utf8::distance(first: str.begin() + start, last: str.begin() + end);
23 }
24
25 size_t code_point_count(const sass::string& str) {
26 return utf8::distance(first: str.begin(), last: str.end());
27 }
28
29 // function that will return the byte offset at a code point position
30 size_t offset_at_position(const sass::string& str, size_t position) {
31 sass::string::const_iterator it = str.begin();
32 utf8::advance(it, n: position, end: str.end());
33 return std::distance(first: str.begin(), last: it);
34 }
35
36 // function that returns number of bytes in a character at offset
37 size_t code_point_size_at_offset(const sass::string& str, size_t offset) {
38 // get iterator from string and forward by offset
39 sass::string::const_iterator stop = str.begin() + offset;
40 // check if beyond boundary
41 if (stop == str.end()) return 0;
42 // advance by one code point
43 utf8::advance(it&: stop, n: 1, end: str.end());
44 // calculate offset for code point
45 return stop - str.begin() - offset;
46 }
47
48 // function that will return a normalized index, given a crazy one
49 size_t normalize_index(int index, size_t len) {
50 long signed_len = static_cast<long>(len);
51 // assuming the index is 1-based
52 // we are returning a 0-based index
53 if (index > 0 && index <= signed_len) {
54 // positive and within string length
55 return index-1;
56 }
57 else if (index > signed_len) {
58 // positive and past string length
59 return len;
60 }
61 else if (index == 0) {
62 return 0;
63 }
64 else if (std::abs(x: (double)index) <= signed_len) {
65 // negative and within string length
66 return index + signed_len;
67 }
68 else {
69 // negative and past string length
70 return 0;
71 }
72 }
73
74 #ifdef _WIN32
75
76 // utf16 functions
77 using std::wstring;
78
79 // convert from utf16/wide string to utf8 string
80 sass::string convert_from_utf16(const wstring& utf16)
81 {
82 sass::string utf8;
83 // pre-allocate expected memory
84 utf8.reserve(sizeof(utf16)/2);
85 utf8::utf16to8(utf16.begin(), utf16.end(),
86 back_inserter(utf8));
87 return utf8;
88 }
89
90 // convert from utf8 string to utf16/wide string
91 wstring convert_to_utf16(const sass::string& utf8)
92 {
93 wstring utf16;
94 // pre-allocate expected memory
95 utf16.reserve(code_point_count(utf8)*2);
96 utf8::utf8to16(utf8.begin(), utf8.end(),
97 back_inserter(utf16));
98 return utf16;
99 }
100
101 #endif
102
103 }
104}
105

source code of gtk/subprojects/libsass/src/utf8_string.cpp