23 "TOK_LSQUARE_BRACKET",
24 "TOK_RSQUARE_BRACKET",
33 static constexpr char whitespaces[] {
' ',
'\n',
'\r',
'\t', 0 };
34 return ( std::find (whitespaces, whitespaces+4, ch ) != whitespaces+4 );
99 Obj_Expect_Comma_Or_End,
105 const auto &parsePair = [&](
String &&key ) {
114 o.
add ( key, std::move(val) );
128 switch ( t->_type ) {
130 auto res = parsePair(
String( std::move(t->_token) ) );
134 state = Obj_Expect_Comma_Or_End;
147 case Obj_Expect_Comma_Or_End: {
148 switch ( t->_type ) {
150 state = Obj_Expect_Pair;
163 case Obj_Expect_Pair: {
165 switch ( t->_type ) {
167 auto res = parsePair(
String( std::move(t->_token) ) );
171 state = Obj_Expect_Comma_Or_End;
197 Arr_Expect_Comma_Or_End,
215 a.add( std::move(*maybeVal) );
216 state = Arr_Expect_Comma_Or_End;
224 a.add( std::move(*maybeVal) );
225 state = Arr_Expect_Comma_Or_End;
228 case Arr_Expect_Comma_Or_End: {
268 switch( begin.
_type ) {
311 }
else if ( next ==
'f' ) {
316 }
else if ( next ==
eofChar() ) {
327 ExpectFraction_or_End,
331 Exponent_ExpectDigit,
336 bool isSigned =
false;
337 bool acceptSign =
true;
339 bool isFloating =
false;
340 bool hasFraction =
false;
347 if ( c ==
'-' && acceptSign ) {
352 }
else if ( c >=
'1' && c <=
'9' ) {
356 }
else if ( c ==
'0' ) {
359 state = ExpectFraction_or_End;
367 case ExpectFraction_or_End: {
374 }
else if ( c ==
'e' || c ==
'E' ) {
377 state = Exponent_Begin;
386 if ( c >=
'0' && c <=
'9' ) {
397 if ( c >=
'0' && c <=
'9' ) {
400 }
else if ( c ==
'e' || c ==
'E' ) {
403 state = Exponent_Begin;
405 }
else if ( c ==
'.' && !hasFraction ) {
417 case Exponent_Begin: {
418 if ( c ==
'+' || c ==
'-' ) {
421 state = Exponent_ExpectDigit;
422 }
else if ( c >=
'0' && c <=
'9') {
433 case Exponent_ExpectDigit:
435 if ( c >=
'0' && c <=
'9' ) {
437 if ( state != Exponent )
443 }
else if ( state == Exponent_ExpectDigit ) {
469 return std::istream::traits_type::eof();
471 auto &input =
_stream->stream();
473 return std::istream::traits_type::eof();
481 return std::istream::traits_type::eof();
483 auto &input =
_stream->stream();
485 return std::istream::traits_type::eof();
498 for ( uint i = 0; i <
str.size(); i++ ) {
502 if ( c !=
str.at(i) )
525 switch ( nextChar ) {
614 }
else if ( c ==
'\\' ) {
630 t.
_token.push_back(
'\b' );
634 t.
_token.push_back(
'\f' );
638 t.
_token.push_back(
'\n' );
642 t.
_token.push_back(
'\r' );
646 t.
_token.push_back(
'\t' );
650 const auto &pop4HexBytes = [&]( ) {
651 std::vector<char> data( 4,
'\0' );
652 for (
int i = 0; i < 4; i++) {
658 if ( (data[i] >=
'0' && data[i] <=
'9' )
659 || (data[i] >=
'A' && data[i] <=
'F' )
660 || (data[i] >=
'a' && data[i] <=
'f' )
672 const auto &convertToCodepoint = [&]( std::vector<char> data ){
676 const auto data1View = std::string_view(data.data(), data.size());
677 auto cp = str::hexCharToValue<uint32_t>( data1View );
684 if ( (*cp) >= 0xd800 && (*cp) <= 0xdbff ) {
686 |
and_then( [&](){
return pop4HexBytes( ); })
687 |
and_then( [&]( std::vector<char> data2 ){
689 const auto data2View = std::string_view(data2.data(), data2.size());
690 const auto lowCp = str::hexCharToValue<uint32_t>( data2View );
696 if ( *lowCp < 0xDC00 || *lowCp > 0xDFFF) {
700 constexpr uint16_t low10BitMask = 0x3FF;
701 uint32_t codepoint = (( (*cp) & low10BitMask ) << 10 ) | ( (*lowCp) & low10BitMask );
702 codepoint += 0x10000;
711 const auto &codepointToUtf8String = [&]( uint32_t cp ) {
718 if ( conv.size () == 0 ) {
728 auto res = pop4HexBytes()
730 |
and_then( codepointToUtf8String );
740 }
else if( c ==
'"' ) {
742 }
else if( c >= 0 && c <= 0x1f ) {
static zyppng::expected< Int > fromString(const std::string &str)
static zyppng::expected< Number > fromString(const std::string &str)
void add(String key_r, Value val_r)
Add key/value pair.
zyppng::expected< Token > parseNullToken()
zyppng::expected< Token > parseBoolToken()
zyppng::expected< Value > finishParseValue(Token begin)
zyppng::expected< Object > parseObject()
zyppng::expected< Token > parseNumberToken()
zyppng::expected< void > consumeString(const std::string &str)
zyppng::expected< Value > parseValue()
zyppng::expected< Value > parse(const InputStream &input_r)
Parse the stream.
zyppng::expected< Token > nextToken()
zyppng::expected< Array > parseArray()
static std::istream::char_type eofChar()
zyppng::expected< Token > parseStringToken()
std::istream::char_type popChar()
std::istream::char_type peekChar()
std::optional< InputStream > _stream
zyppng::expected< T > makeParseError(const std::string &message, exception_detail::CodeLocation &&loc)
static zyppng::expected< UInt > fromString(const std::string &str)
static expected success(ConsParams &&...params)
String related utilities and Regular expression matching.
static bool isWhiteSpace(const char ch)
constexpr std::string_view TOK_NAMES[Parser::Token::TOK_COUNT]
std::string codepointToUtf8String(uint32_t unichar)
bool validateUtf8(std::string_view str)
std::string hexstring(char n, int w=4)
auto and_then(Fun &&function)
static expected< std::decay_t< Type >, Err > make_expected_success(Type &&t)
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
#define ZYPP_EX_CODELOCATION
Create CodeLocation object storing the current location.
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.