Bitcoin Core
31.1.0
P2P Digital Currency
Toggle main menu visibility
Loading...
Searching...
No Matches
src
univalue
include
univalue_utffilter.h
Go to the documentation of this file.
1
// Copyright 2016 Wladimir J. van der Laan
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or https://opensource.org/licenses/mit-license.php.
4
#ifndef BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_UTFFILTER_H
5
#define BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_UTFFILTER_H
6
7
#include <string>
8
13
class
JSONUTF8StringFilter
14
{
15
public
:
16
explicit
JSONUTF8StringFilter
(std::string& s)
17
:
str
(s)
18
{
19
}
20
// Write single 8-bit char (may be part of UTF-8 sequence)
21
void
push_back
(
unsigned
char
ch)
22
{
23
if
(
state
== 0) {
24
if
(ch < 0x80)
// 7-bit ASCII, fast direct pass-through
25
str
.push_back(ch);
26
else
if
(ch < 0xc0)
// Mid-sequence character, invalid in this state
27
is_valid
=
false
;
28
else
if
(ch < 0xe0) {
// Start of 2-byte sequence
29
codepoint
= (ch & 0x1f) << 6;
30
state
= 6;
31
}
else
if
(ch < 0xf0) {
// Start of 3-byte sequence
32
codepoint
= (ch & 0x0f) << 12;
33
state
= 12;
34
}
else
if
(ch < 0xf8) {
// Start of 4-byte sequence
35
codepoint
= (ch & 0x07) << 18;
36
state
= 18;
37
}
else
// Reserved, invalid
38
is_valid
=
false
;
39
}
else
{
40
if
((ch & 0xc0) != 0x80)
// Not a continuation, invalid
41
is_valid
=
false
;
42
state
-= 6;
43
codepoint
|= (ch & 0x3f) <<
state
;
44
if
(
state
== 0)
45
push_back_u
(
codepoint
);
46
}
47
}
48
// Write codepoint directly, possibly collating surrogate pairs
49
void
push_back_u
(
unsigned
int
codepoint_)
50
{
51
if
(
state
)
// Only accept full codepoints in open state
52
is_valid
=
false
;
53
if
(codepoint_ >= 0xD800 && codepoint_ < 0xDC00) {
// First half of surrogate pair
54
if
(
surpair
)
// Two subsequent surrogate pair openers - fail
55
is_valid
=
false
;
56
else
57
surpair
= codepoint_;
58
}
else
if
(codepoint_ >= 0xDC00 && codepoint_ < 0xE000) {
// Second half of surrogate pair
59
if
(
surpair
) {
// Open surrogate pair, expect second half
60
// Compute code point from UTF-16 surrogate pair
61
append_codepoint
(0x10000 | ((
surpair
- 0xD800)<<10) | (codepoint_ - 0xDC00));
62
surpair
= 0;
63
}
else
// Second half doesn't follow a first half - fail
64
is_valid
=
false
;
65
}
else
{
66
if
(
surpair
)
// First half of surrogate pair not followed by second - fail
67
is_valid
=
false
;
68
else
69
append_codepoint
(codepoint_);
70
}
71
}
72
// Check that we're in a state where the string can be ended
73
// No open sequences, no open surrogate pairs, etc
74
bool
finalize
()
75
{
76
if
(
state
||
surpair
)
77
is_valid
=
false
;
78
return
is_valid
;
79
}
80
private
:
81
std::string &
str
;
82
bool
is_valid
{
true
};
83
// Current UTF-8 decoding state
84
unsigned
int
codepoint
{0};
85
int
state
{0};
// Top bit to be filled in for next UTF-8 byte, or 0
86
87
// Keep track of the following state to handle the following section of
88
// RFC4627:
89
//
90
// To escape an extended character that is not in the Basic Multilingual
91
// Plane, the character is represented as a twelve-character sequence,
92
// encoding the UTF-16 surrogate pair. So, for example, a string
93
// containing only the G clef character (U+1D11E) may be represented as
94
// "\uD834\uDD1E".
95
//
96
// Two subsequent \u.... may have to be replaced with one actual codepoint.
97
unsigned
int
surpair
{0};
// First half of open UTF-16 surrogate pair, or 0
98
99
void
append_codepoint
(
unsigned
int
codepoint_)
100
{
101
if
(codepoint_ <= 0x7f)
102
str
.push_back((
char
)codepoint_);
103
else
if
(codepoint_ <= 0x7FF) {
104
str
.push_back((
char
)(0xC0 | (codepoint_ >> 6)));
105
str
.push_back((
char
)(0x80 | (codepoint_ & 0x3F)));
106
}
else
if
(codepoint_ <= 0xFFFF) {
107
str
.push_back((
char
)(0xE0 | (codepoint_ >> 12)));
108
str
.push_back((
char
)(0x80 | ((codepoint_ >> 6) & 0x3F)));
109
str
.push_back((
char
)(0x80 | (codepoint_ & 0x3F)));
110
}
else
if
(codepoint_ <= 0x1FFFFF) {
111
str
.push_back((
char
)(0xF0 | (codepoint_ >> 18)));
112
str
.push_back((
char
)(0x80 | ((codepoint_ >> 12) & 0x3F)));
113
str
.push_back((
char
)(0x80 | ((codepoint_ >> 6) & 0x3F)));
114
str
.push_back((
char
)(0x80 | (codepoint_ & 0x3F)));
115
}
116
}
117
};
118
119
#endif
// BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_UTFFILTER_H
JSONUTF8StringFilter::surpair
unsigned int surpair
Definition
univalue_utffilter.h:97
JSONUTF8StringFilter::is_valid
bool is_valid
Definition
univalue_utffilter.h:82
JSONUTF8StringFilter::codepoint
unsigned int codepoint
Definition
univalue_utffilter.h:84
JSONUTF8StringFilter::push_back
void push_back(unsigned char ch)
Definition
univalue_utffilter.h:21
JSONUTF8StringFilter::finalize
bool finalize()
Definition
univalue_utffilter.h:74
JSONUTF8StringFilter::state
int state
Definition
univalue_utffilter.h:85
JSONUTF8StringFilter::push_back_u
void push_back_u(unsigned int codepoint_)
Definition
univalue_utffilter.h:49
JSONUTF8StringFilter::append_codepoint
void append_codepoint(unsigned int codepoint_)
Definition
univalue_utffilter.h:99
JSONUTF8StringFilter::str
std::string & str
Definition
univalue_utffilter.h:81
JSONUTF8StringFilter::JSONUTF8StringFilter
JSONUTF8StringFilter(std::string &s)
Definition
univalue_utffilter.h:16
Generated on
for Bitcoin Core by
1.17.0