Joedb 9.1.4
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
type_io.cpp
Go to the documentation of this file.
1#include "joedb/ui/type_io.h"
2#include "external/wide_char_display_width.h"
3
4#include <iostream>
5#include <string>
6
8
9namespace joedb
10{
11 /////////////////////////////////////////////////////////////////////////////
12 std::string read_string(std::istream &in)
13 /////////////////////////////////////////////////////////////////////////////
14 {
15 std::string result;
16
17 char c;
18
19 while (true)
20 {
21 if (!in.get(c))
22 return result;
23 if (c != ' ')
24 break;
25 }
26
27 const bool is_quoted = c == '"';
28 if (is_quoted)
29 in.get(c);
30
31 while ((is_quoted && c != '"') || (!is_quoted && c != ' '))
32 {
33 if (c == '\\')
34 {
35 in.get(c);
36
37 if (c == 'x')
38 {
39 char c1;
40 char c0;
41 in.get(c1).get(c0);
42 const uint8_t n1 = get_hex_digit_from_char(c1);
43 const uint8_t n0 = get_hex_digit_from_char(c0);
44 c = char((n1 << 4) | n0);
45 }
46 else if (c >= '0' && c <= '9')
47 {
48 char c1;
49 char c0;
50 in.get(c1).get(c0);
51 const uint8_t n2 = uint8_t(c - '0');
52 const uint8_t n1 = uint8_t(c1 - '0');
53 const uint8_t n0 = uint8_t(c0 - '0');
54 c = char((n2 << 6) | (n1 << 3) | n0);
55 }
56 }
57
58 result.push_back(c);
59
60 if (!in.get(c))
61 break;
62 }
63
64 return result;
65 }
66
67 /////////////////////////////////////////////////////////////////////////////
69 /////////////////////////////////////////////////////////////////////////////
70 {
71 if (c >= '0' && c <= '9')
72 return uint8_t(c - '0');
73 else if (c >= 'a' && c <= 'f')
74 return uint8_t(10 + c - 'a');
75 else
76 return 0;
77 }
78
79 /////////////////////////////////////////////////////////////////////////////
80 void write_hexa_character(std::ostream &out, uint8_t c)
81 /////////////////////////////////////////////////////////////////////////////
82 {
83 out.put('\\');
84 out.put('x');
85 out.put(get_hex_char_from_digit(uint8_t(c >> 4)));
86 out.put(get_hex_char_from_digit(uint8_t(c & 0x0f)));
87 }
88
89 /////////////////////////////////////////////////////////////////////////////
90 void write_sql_string(std::ostream &out, const std::string &s)
91 /////////////////////////////////////////////////////////////////////////////
92 {
93 out.put('X');
94 out.put('\'');
95 for (const char c: s)
96 {
97 out.put(get_hex_char_from_digit(uint8_t(c >> 4)));
98 out.put(get_hex_char_from_digit(uint8_t(c & 0x0f)));
99 }
100 out.put('\'');
101 }
102
103 /////////////////////////////////////////////////////////////////////////////
104 size_t utf8_display_size(const std::string &s)
105 /////////////////////////////////////////////////////////////////////////////
106 {
107 size_t result = 0;
108
109 for (size_t i = 0; i < s.size();)
110 {
111 const uint32_t wide_char = read_utf8_char(i, s);
112 const int width = wide_char_display_width(uint32_t(wide_char));
113 if (width > 0)
114 result += size_t(wide_char_display_width(uint32_t(wide_char)));
115 }
116
117 return result;
118 }
119
120 /////////////////////////////////////////////////////////////////////////////
121 uint32_t read_utf8_char(size_t &i, const std::string &s)
122 /////////////////////////////////////////////////////////////////////////////
123 {
124 const uint8_t *p = (reinterpret_cast<const uint8_t *>(s.c_str()) + i);
125
126 uint32_t result;
127
128 if ((p[0] & 0xe0) == 0xc0 && i + 1 < s.size())
129 {
130 result = (uint32_t(p[0]) << 6) +
131 (uint32_t(p[1]) ) - uint32_t(0x3080UL);
132 i += 2;
133 }
134 else if ((p[0] & 0xf0) == 0xe0 && i + 2 < s.size())
135 {
136 result = (uint32_t(p[0]) << 12) +
137 (uint32_t(p[1]) << 6) +
138 (uint32_t(p[2]) ) - uint32_t(0xe2080UL);
139 i += 3;
140 }
141 else if ((p[0] & 0xf8) == 0xf0 && i + 3 < s.size())
142 {
143 result = (uint32_t(p[0]) << 18) +
144 (uint32_t(p[1]) << 12) +
145 (uint32_t(p[2]) << 6) +
146 (uint32_t(p[3]) ) - uint32_t(0x3c82080UL);
147 i += 4;
148 }
149 else
150 {
151 result = p[0];
152 i += 1;
153 }
154
155 return result;
156 }
157
158 /////////////////////////////////////////////////////////////////////////////
160 /////////////////////////////////////////////////////////////////////////////
161 (
162 std::ostream &out,
163 const std::string &s,
164 size_t width,
165 bool flush_left
166 )
167 {
168 size_t length = 0;
169 std::string displayed;
170
171 for (size_t i = 0; s.c_str()[i];)
172 {
173 const size_t previous_i = i;
174 const uint32_t wide_char = read_utf8_char(i, s);
175 const size_t char_width = size_t(wide_char_display_width(wide_char));
176
177 if (length + char_width < width ||
178 (length + char_width == width && s.c_str()[i] == 0))
179 {
180 length += char_width;
181 for (size_t j = previous_i; j < i; j++)
182 displayed += s[j];
183 }
184 else
185 {
186 length += 1;
187 displayed += "…";
188 break;
189 }
190 }
191
192 if (flush_left)
193 out << displayed;
194
195 while (length < width)
196 {
197 out << ' ';
198 length++;
199 }
200
201 if (!flush_left)
202 out << displayed;
203 }
204
205 /////////////////////////////////////////////////////////////////////////////
206 int8_t read_int8(std::istream &in)
207 /////////////////////////////////////////////////////////////////////////////
208 {
209 int result;
210 in >> result;
211 return int8_t(result);
212 }
213
214 /////////////////////////////////////////////////////////////////////////////
215 bool read_boolean(std::istream &in)
216 /////////////////////////////////////////////////////////////////////////////
217 {
218 std::string word;
219 in >> word;
220
221 if (word == "true" || word == "1")
222 return true;
223 else if (word == "false" || word == "0")
224 return false;
225 else
226 {
227 in.setstate(std::ios::failbit);
228 return false;
229 }
230 }
231
232 /////////////////////////////////////////////////////////////////////////////
233 void write_boolean(std::ostream &out, bool value)
234 /////////////////////////////////////////////////////////////////////////////
235 {
236 if (value)
237 out << "true";
238 else
239 out << "false";
240 }
241
242 /////////////////////////////////////////////////////////////////////////////
243 void write_blob(std::ostream &out, Blob blob)
244 /////////////////////////////////////////////////////////////////////////////
245 {
246 out << blob.get_position();
247 }
248
249 /////////////////////////////////////////////////////////////////////////////
250 Blob read_blob(std::istream &in)
251 /////////////////////////////////////////////////////////////////////////////
252 {
253 int64_t position = 0;
254 in >> position;
255 return Blob(position);
256 }
257}
int64_t get_position() const noexcept
Definition Blob.h:28
uint8_t get_hex_digit_from_char(char c)
Definition type_io.cpp:68
void write_boolean(std::ostream &out, bool value)
Definition type_io.cpp:233
void write_sql_string(std::ostream &out, const std::string &s)
Definition type_io.cpp:90
uint32_t read_utf8_char(size_t &i, const std::string &s)
Definition type_io.cpp:121
void write_justified(std::ostream &out, const std::string &s, size_t width, bool flush_left)
Definition type_io.cpp:161
void write_hexa_character(std::ostream &out, uint8_t c)
Definition type_io.cpp:80
bool read_boolean(std::istream &in)
Definition type_io.cpp:215
size_t utf8_display_size(const std::string &s)
Definition type_io.cpp:104
int8_t read_int8(std::istream &in)
Definition type_io.cpp:206
void write_blob(std::ostream &out, Blob blob)
Definition type_io.cpp:243
char get_hex_char_from_digit(uint8_t n)
std::string read_string(std::istream &in)
Definition type_io.cpp:12
Blob read_blob(std::istream &in)
Definition type_io.cpp:250
Definition Blob.h:7